Initial commit
This commit is contained in:
@@ -0,0 +1,419 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Configuration\FlexForm;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Contains functions for manipulating flex form data
|
||||
*/
|
||||
class FlexFormTools
|
||||
{
|
||||
/**
|
||||
* If set, the charset of data XML is converted to system charset.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $convertCharset = false;
|
||||
|
||||
/**
|
||||
* If set, section indexes are re-numbered before processing
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $reNumberIndexesOfSectionData = false;
|
||||
|
||||
/**
|
||||
* Contains data structure when traversing flexform
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $traverseFlexFormXMLData_DS = array();
|
||||
|
||||
/**
|
||||
* Contains data array when traversing flexform
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $traverseFlexFormXMLData_Data = array();
|
||||
|
||||
/**
|
||||
* Options for array2xml() for flexform.
|
||||
* This will map the weird keys from the internal array to tags that could potentially be checked with a DTD/schema
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $flexArray2Xml_options = array(
|
||||
'parentTagMap' => array(
|
||||
'data' => 'sheet',
|
||||
'sheet' => 'language',
|
||||
'language' => 'field',
|
||||
'el' => 'field',
|
||||
'field' => 'value',
|
||||
'field:el' => 'el',
|
||||
'el:_IS_NUM' => 'section',
|
||||
'section' => 'itemType'
|
||||
),
|
||||
'disableTypeAttrib' => 2
|
||||
);
|
||||
|
||||
/**
|
||||
* Reference to object called
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $callBackObj = null;
|
||||
|
||||
/**
|
||||
* Used for accumulation of clean XML
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $cleanFlexFormXML = array();
|
||||
|
||||
/**
|
||||
* Handler for Flex Forms
|
||||
*
|
||||
* @param string $table The table name of the record
|
||||
* @param string $field The field name of the flexform field to work on
|
||||
* @param array $row The record data array
|
||||
* @param object $callBackObj Object in which the call back function is located
|
||||
* @param string $callBackMethod_value Method name of call back function in object for values
|
||||
* @return bool|string If TRUE, error happened (error string returned)
|
||||
*/
|
||||
public function traverseFlexFormXMLData($table, $field, $row, $callBackObj, $callBackMethod_value)
|
||||
{
|
||||
if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$field])) {
|
||||
return 'TCA table/field was not defined.';
|
||||
}
|
||||
$this->callBackObj = $callBackObj;
|
||||
// Get Data Structure:
|
||||
$dataStructArray = BackendUtility::getFlexFormDS($GLOBALS['TCA'][$table]['columns'][$field]['config'], $row, $table, $field);
|
||||
// If data structure was ok, proceed:
|
||||
if (is_array($dataStructArray)) {
|
||||
// Get flexform XML data:
|
||||
$xmlData = $row[$field];
|
||||
// Convert charset:
|
||||
if ($this->convertCharset) {
|
||||
$xmlHeaderAttributes = GeneralUtility::xmlGetHeaderAttribs($xmlData);
|
||||
$storeInCharset = strtolower($xmlHeaderAttributes['encoding']);
|
||||
if ($storeInCharset) {
|
||||
$currentCharset = $GLOBALS['LANG']->charSet;
|
||||
$xmlData = $GLOBALS['LANG']->csConvObj->conv($xmlData, $storeInCharset, $currentCharset, 1);
|
||||
}
|
||||
}
|
||||
$editData = GeneralUtility::xml2array($xmlData);
|
||||
if (!is_array($editData)) {
|
||||
return 'Parsing error: ' . $editData;
|
||||
}
|
||||
// Language settings:
|
||||
$langChildren = $dataStructArray['meta']['langChildren'] ? 1 : 0;
|
||||
$langDisabled = $dataStructArray['meta']['langDisable'] ? 1 : 0;
|
||||
// Empty or invalid <meta>
|
||||
if (!is_array($editData['meta'])) {
|
||||
$editData['meta'] = array();
|
||||
}
|
||||
$editData['meta']['currentLangId'] = array();
|
||||
$languages = $this->getAvailableLanguages();
|
||||
foreach ($languages as $lInfo) {
|
||||
$editData['meta']['currentLangId'][] = $lInfo['ISOcode'];
|
||||
}
|
||||
if (empty($editData['meta']['currentLangId'])) {
|
||||
$editData['meta']['currentLangId'] = array('DEF');
|
||||
}
|
||||
$editData['meta']['currentLangId'] = array_unique($editData['meta']['currentLangId']);
|
||||
if ($langChildren || $langDisabled) {
|
||||
$lKeys = array('DEF');
|
||||
} else {
|
||||
$lKeys = $editData['meta']['currentLangId'];
|
||||
}
|
||||
// Tabs sheets
|
||||
if (is_array($dataStructArray['sheets'])) {
|
||||
$sKeys = array_keys($dataStructArray['sheets']);
|
||||
} else {
|
||||
$sKeys = array('sDEF');
|
||||
}
|
||||
// Traverse languages:
|
||||
foreach ($lKeys as $lKey) {
|
||||
foreach ($sKeys as $sheet) {
|
||||
$sheetCfg = $dataStructArray['sheets'][$sheet];
|
||||
list($dataStruct, $sheet) = GeneralUtility::resolveSheetDefInDS($dataStructArray, $sheet);
|
||||
// Render sheet:
|
||||
if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el'])) {
|
||||
// Separate language key
|
||||
$lang = 'l' . $lKey;
|
||||
$PA['vKeys'] = $langChildren && !$langDisabled ? $editData['meta']['currentLangId'] : array('DEF');
|
||||
$PA['lKey'] = $lang;
|
||||
$PA['callBackMethod_value'] = $callBackMethod_value;
|
||||
$PA['table'] = $table;
|
||||
$PA['field'] = $field;
|
||||
$PA['uid'] = $row['uid'];
|
||||
$this->traverseFlexFormXMLData_DS = &$dataStruct;
|
||||
$this->traverseFlexFormXMLData_Data = &$editData;
|
||||
// Render flexform:
|
||||
$this->traverseFlexFormXMLData_recurse($dataStruct['ROOT']['el'], $editData['data'][$sheet][$lang], $PA, 'data/' . $sheet . '/' . $lang);
|
||||
} else {
|
||||
return 'Data Structure ERROR: No ROOT element found for sheet "' . $sheet . '".';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 'Data Structure ERROR: ' . $dataStructArray;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively traversing flexform data according to data structure and element data
|
||||
*
|
||||
* @param array $dataStruct (Part of) data structure array that applies to the sub section of the flexform data we are processing
|
||||
* @param array $editData (Part of) edit data array, reflecting current part of data structure
|
||||
* @param array $PA Additional parameters passed.
|
||||
* @param string $path Telling the "path" to the element in the flexform XML
|
||||
* @return array
|
||||
*/
|
||||
public function traverseFlexFormXMLData_recurse($dataStruct, $editData, &$PA, $path = '')
|
||||
{
|
||||
if (is_array($dataStruct)) {
|
||||
foreach ($dataStruct as $key => $value) {
|
||||
// The value of each entry must be an array.
|
||||
if (is_array($value)) {
|
||||
if ($value['type'] == 'array') {
|
||||
// Array (Section) traversal
|
||||
if ($value['section']) {
|
||||
$cc = 0;
|
||||
if (is_array($editData[$key]['el'])) {
|
||||
if ($this->reNumberIndexesOfSectionData) {
|
||||
$temp = array();
|
||||
$c3 = 0;
|
||||
foreach ($editData[$key]['el'] as $v3) {
|
||||
$temp[++$c3] = $v3;
|
||||
}
|
||||
$editData[$key]['el'] = $temp;
|
||||
}
|
||||
foreach ($editData[$key]['el'] as $k3 => $v3) {
|
||||
if (is_array($v3)) {
|
||||
$cc = $k3;
|
||||
$theType = key($v3);
|
||||
$theDat = $v3[$theType];
|
||||
$newSectionEl = $value['el'][$theType];
|
||||
if (is_array($newSectionEl)) {
|
||||
$this->traverseFlexFormXMLData_recurse(array($theType => $newSectionEl), array($theType => $theDat), $PA, $path . '/' . $key . '/el/' . $cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Array traversal
|
||||
if (is_array($editData) && is_array($editData[$key])) {
|
||||
$this->traverseFlexFormXMLData_recurse($value['el'], $editData[$key]['el'], $PA, $path . '/' . $key . '/el');
|
||||
}
|
||||
}
|
||||
} elseif (is_array($value['TCEforms']['config'])) {
|
||||
// Processing a field value:
|
||||
foreach ($PA['vKeys'] as $vKey) {
|
||||
$vKey = 'v' . $vKey;
|
||||
// Call back
|
||||
if ($PA['callBackMethod_value'] && is_array($editData) && is_array($editData[$key])) {
|
||||
$this->executeCallBackMethod($PA['callBackMethod_value'], array($value, $editData[$key][$vKey], $PA, $path . '/' . $key . '/' . $vKey, $this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute method on callback object
|
||||
*
|
||||
* @param string $methodName Method name to call
|
||||
* @param array $parameterArray Parameters
|
||||
* @return mixed Result of callback object
|
||||
*/
|
||||
protected function executeCallBackMethod($methodName, array $parameterArray)
|
||||
{
|
||||
return call_user_func_array(array($this->callBackObj, $methodName), $parameterArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of available languages to use for FlexForm operations
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAvailableLanguages()
|
||||
{
|
||||
$isL = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables');
|
||||
// Find all language records in the system
|
||||
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
'language_isocode,static_lang_isocode,title,uid',
|
||||
'sys_language',
|
||||
'pid=0' . BackendUtility::deleteClause('sys_language'),
|
||||
'',
|
||||
'title'
|
||||
);
|
||||
// Traverse them
|
||||
$output = array();
|
||||
$output[0] = array(
|
||||
'uid' => 0,
|
||||
'title' => 'Default language',
|
||||
'ISOcode' => 'DEF'
|
||||
);
|
||||
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
|
||||
$output[$row['uid']] = $row;
|
||||
if (!empty($row['language_isocode'])) {
|
||||
$output[$row['uid']]['ISOcode'] = $row['language_isocode'];
|
||||
} elseif ($isL && $row['static_lang_isocode']) {
|
||||
\TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog('Usage of the field "static_lang_isocode" is discouraged, and will stop working with CMS 8. Use the built-in language field "language_isocode" in your sys_language records.');
|
||||
$rr = BackendUtility::getRecord('static_languages', $row['static_lang_isocode'], 'lg_iso_2');
|
||||
if ($rr['lg_iso_2']) {
|
||||
$output[$row['uid']]['ISOcode'] = $rr['lg_iso_2'];
|
||||
}
|
||||
}
|
||||
if (!$output[$row['uid']]['ISOcode']) {
|
||||
unset($output[$row['uid']]);
|
||||
}
|
||||
}
|
||||
$GLOBALS['TYPO3_DB']->sql_free_result($res);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/***********************************
|
||||
*
|
||||
* Processing functions
|
||||
*
|
||||
***********************************/
|
||||
/**
|
||||
* Cleaning up FlexForm XML to hold only the values it may according to its Data Structure. Also the order of tags will follow that of the data structure.
|
||||
* BE CAREFUL: DO not clean records in workspaces unless IN the workspace! The Data Structure might resolve falsely on a workspace record when cleaned from Live workspace.
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @param string $field Field name of the flex form field in which the XML is found that should be cleaned.
|
||||
* @param array $row The record
|
||||
* @return string Clean XML from FlexForm field
|
||||
*/
|
||||
public function cleanFlexFormXML($table, $field, $row)
|
||||
{
|
||||
// New structure:
|
||||
$this->cleanFlexFormXML = array();
|
||||
// Create and call iterator object:
|
||||
$flexObj = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class);
|
||||
$flexObj->reNumberIndexesOfSectionData = true;
|
||||
$flexObj->traverseFlexFormXMLData($table, $field, $row, $this, 'cleanFlexFormXML_callBackFunction');
|
||||
return $this->flexArray2Xml($this->cleanFlexFormXML, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call back function for \TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools class
|
||||
* Basically just setting the value in a new array (thus cleaning because only values that are valid are visited!)
|
||||
*
|
||||
* @param array $dsArr Data structure for the current value
|
||||
* @param mixed $data Current value
|
||||
* @param array $PA Additional configuration used in calling function
|
||||
* @param string $path Path of value in DS structure
|
||||
* @param FlexFormTools $pObj caller
|
||||
* @return void
|
||||
*/
|
||||
public function cleanFlexFormXML_callBackFunction($dsArr, $data, $PA, $path, $pObj)
|
||||
{
|
||||
// Just setting value in our own result array, basically replicating the structure:
|
||||
$pObj->setArrayValueByPath($path, $this->cleanFlexFormXML, $data);
|
||||
// Looking if an "extension" called ".vDEFbase" is found and if so, accept that too:
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase']) {
|
||||
$vDEFbase = $pObj->getArrayValueByPath($path . '.vDEFbase', $pObj->traverseFlexFormXMLData_Data);
|
||||
if (isset($vDEFbase)) {
|
||||
$pObj->setArrayValueByPath($path . '.vDEFbase', $this->cleanFlexFormXML, $vDEFbase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************
|
||||
*
|
||||
* Multi purpose functions
|
||||
*
|
||||
***********************************/
|
||||
/**
|
||||
* Get a value from a multi-dimensional array by giving a path "../../.." pointing to the element
|
||||
*
|
||||
* @param string $pathArray The path pointing to the value field, eg. test/2/title to access $array['test'][2]['title']
|
||||
* @param array $array Array to get value from. Passed by reference so the value returned can be used to change the value in the array!
|
||||
* @return mixed Value returned
|
||||
*/
|
||||
public function &getArrayValueByPath($pathArray, &$array)
|
||||
{
|
||||
if (!is_array($pathArray)) {
|
||||
$pathArray = explode('/', $pathArray);
|
||||
}
|
||||
if (is_array($array) && !empty($pathArray)) {
|
||||
$key = array_shift($pathArray);
|
||||
if (isset($array[$key])) {
|
||||
if (empty($pathArray)) {
|
||||
return $array[$key];
|
||||
}
|
||||
return $this->getArrayValueByPath($pathArray, $array[$key]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value in a multi-dimensional array by giving a path "../../.." pointing to the element
|
||||
*
|
||||
* @param string $pathArray The path pointing to the value field, eg. test/2/title to access $array['test'][2]['title']
|
||||
* @param array $array Array to set value in. Passed by reference so the value returned can be used to change the value in the array!
|
||||
* @param mixed $value Value to set
|
||||
* @return mixed Value returned
|
||||
*/
|
||||
public function setArrayValueByPath($pathArray, &$array, $value)
|
||||
{
|
||||
if (isset($value)) {
|
||||
if (!is_array($pathArray)) {
|
||||
$pathArray = explode('/', $pathArray);
|
||||
}
|
||||
if (is_array($array) && !empty($pathArray)) {
|
||||
$key = array_shift($pathArray);
|
||||
if (empty($pathArray)) {
|
||||
$array[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
if (!isset($array[$key])) {
|
||||
$array[$key] = array();
|
||||
}
|
||||
return $this->setArrayValueByPath($pathArray, $array[$key], $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert FlexForm data array to XML
|
||||
*
|
||||
* @param array $array Array to output in <T3FlexForms> XML
|
||||
* @param bool $addPrologue If set, the XML prologue is returned as well.
|
||||
* @return string XML content.
|
||||
*/
|
||||
public function flexArray2Xml($array, $addPrologue = false)
|
||||
{
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['flexformForceCDATA']) {
|
||||
$this->flexArray2Xml_options['useCDATA'] = 1;
|
||||
}
|
||||
$options = $GLOBALS['TYPO3_CONF_VARS']['BE']['niceFlexFormXMLtags'] ? $this->flexArray2Xml_options : array();
|
||||
$spaceInd = $GLOBALS['TYPO3_CONF_VARS']['BE']['compactFlexFormXML'] ? -1 : 4;
|
||||
$output = GeneralUtility::array2xml($array, '', 0, 'T3FlexForms', $spaceInd, $options);
|
||||
if ($addPrologue) {
|
||||
$output = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>' . LF . $output;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains CLEARGIF class object.
|
||||
*/
|
||||
class ClearGifContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* Rendering the cObject, CLEARGIF
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
$width = isset($conf['width.']) ? $this->cObj->stdWrap($conf['width'], $conf['width.']) : $conf['width'];
|
||||
if (!$width) {
|
||||
$width = 1;
|
||||
}
|
||||
$height = isset($conf['height.']) ? $this->cObj->stdWrap($conf['height'], $conf['height.']) : $conf['height'];
|
||||
if (!$height) {
|
||||
$height = 1;
|
||||
}
|
||||
$wrap = isset($conf['wrap.']) ? $this->cObj->stdWrap($conf['wrap'], $conf['wrap.']) : $conf['wrap'];
|
||||
if (!$wrap) {
|
||||
$wrap = '|<br />';
|
||||
}
|
||||
$theValue = $this->cObj->wrap('<span style="width: ' . $width . 'px; height: ' . $height . 'px;"></span>', $wrap);
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$theValue = $this->cObj->stdWrap($theValue, $conf['stdWrap.']);
|
||||
}
|
||||
return $theValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains COLUMNS content object.
|
||||
*/
|
||||
class ColumnsContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* Rendering the cObject, COLUMNS
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
if (empty($conf) || !empty($conf['if.']) && !$this->cObj->checkIf($conf['if.'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
$tdRowCount = 0;
|
||||
$tableParams = isset($conf['tableParams.']) ? $this->cObj->stdWrap($conf['tableParams'], $conf['tableParams.']) : $conf['tableParams'];
|
||||
$tableParams = $tableParams ? ' ' . $tableParams : ' border="0" cellspacing="0" cellpadding="0"';
|
||||
$TDparams = isset($conf['TDParams.']) ? $this->cObj->stdWrap($conf['TDParams'], $conf['TDParams.']) : $conf['TDParams'];
|
||||
$TDparams = $TDparams ? ' ' . $TDparams : ' valign="top"';
|
||||
$rows = isset($conf['rows.']) ? $this->cObj->stdWrap($conf['rows'], $conf['rows.']) : $conf['rows'];
|
||||
$rows = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($rows, 2, 20);
|
||||
$totalWidth = isset($conf['totalWidth.']) ? (int)$this->cObj->stdWrap($conf['totalWidth'], $conf['totalWidth.']) : (int)$conf['totalWidth'];
|
||||
$totalGapWidth = 0;
|
||||
$gapData = array(
|
||||
'gapWidth' => isset($conf['gapWidth.']) ? $this->cObj->stdWrap($conf['gapWidth'], $conf['gapWidth.']) : $conf['gapWidth'],
|
||||
'gapBgCol' => isset($conf['gapBgCol.']) ? $this->cObj->stdWrap($conf['gapBgCol'], $conf['gapBgCol.']) : $conf['gapBgCol'],
|
||||
'gapLineThickness' => isset($conf['gapLineThickness.']) ? $this->cObj->stdWrap($conf['gapLineThickness'], $conf['gapLineThickness.']) : $conf['gapLineThickness'],
|
||||
'gapLineCol' => isset($conf['gapLineCol.']) ? $this->cObj->stdWrap($conf['gapLineCol'], $conf['gapLineCol.']) : $conf['gapLineCol']
|
||||
);
|
||||
$gapData = $GLOBALS['TSFE']->tmpl->splitConfArray($gapData, $rows - 1);
|
||||
foreach ($gapData as $val) {
|
||||
$totalGapWidth += (int)$val['gapWidth'];
|
||||
}
|
||||
if ($totalWidth) {
|
||||
$columnWidth = ceil(($totalWidth - $totalGapWidth) / $rows);
|
||||
$TDparams .= ' width="' . $columnWidth . '"';
|
||||
$tableParams .= ' width="' . $totalWidth . '"';
|
||||
} else {
|
||||
$TDparams .= ' width="' . floor(100 / $rows) . '%"';
|
||||
$tableParams .= ' width="100%"';
|
||||
}
|
||||
for ($a = 1; $a <= $rows; $a++) {
|
||||
$tdRowCount++;
|
||||
$content .= '<td' . $TDparams . '>';
|
||||
$content .= $this->cObj->cObjGetSingle($conf[$a], $conf[$a . '.'], $a);
|
||||
$content .= '</td>';
|
||||
if ($a < $rows) {
|
||||
$gapConf = $gapData[$a - 1];
|
||||
$gapWidth = (int)$gapConf['gapWidth'];
|
||||
if ($gapWidth) {
|
||||
$tdPar = $gapConf['gapBgCol'] ? ' bgcolor="' . $gapConf['gapBgCol'] . '"' : '';
|
||||
$gapLine = (int)$gapConf['gapLineThickness'];
|
||||
if ($gapLine) {
|
||||
$gapSurround = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange(($gapWidth - $gapLine) / 2, 1, 1000);
|
||||
// right gap
|
||||
$content .= '<td' . $tdPar . '><span style="width: ' . $gapSurround . 'px; height: 1px;"></span></td>';
|
||||
$tdRowCount++;
|
||||
// line:
|
||||
$GtdPar = $gapConf['gapLineCol'] ? ' bgcolor="' . $gapConf['gapLineCol'] . '"' : ' bgcolor="black"';
|
||||
$content .= '<td' . $GtdPar . '><span style="width: ' . $gapLine . 'px; height: 1px;"></span></td>';
|
||||
$tdRowCount++;
|
||||
// left gap
|
||||
$content .= '<td' . $tdPar . '><span style="width: ' . $gapSurround . 'px; height: 1px;"></span></td>';
|
||||
$tdRowCount++;
|
||||
} else {
|
||||
$content .= '<td' . $tdPar . '><span style="width: ' . $gapWidth . 'px; height: 1px;"></span></td>';
|
||||
$tdRowCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$content = '<tr>' . $content . '</tr>';
|
||||
$content = '<table' . $tableParams . '>' . $content . '</table>';
|
||||
if ($conf['after'] || isset($conf['after.'])) {
|
||||
$content .= $this->cObj->cObjGetSingle($conf['after'], $conf['after.'], 'after');
|
||||
}
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains CTABLE content object.
|
||||
*/
|
||||
class ContentTableContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* Rendering the cObject, CTABLE
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
$controlTable = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(TableRenderer::class);
|
||||
$tableParams = isset($conf['tableParams.']) ? $this->cObj->stdWrap($conf['tableParams'], $conf['tableParams.']) : $conf['tableParams'];
|
||||
if ($tableParams) {
|
||||
$controlTable->tableParams = $tableParams;
|
||||
}
|
||||
// loads the pagecontent
|
||||
$conf['cWidth'] = isset($conf['cWidth.']) ? $this->cObj->stdWrap($conf['cWidth'], $conf['cWidth.']) : $conf['cWidth'];
|
||||
$controlTable->contentW = $conf['cWidth'];
|
||||
// loads the menues if any
|
||||
if (is_array($conf['c.'])) {
|
||||
$controlTable->content = $this->cObj->cObjGet($conf['c.'], 'c.');
|
||||
$contentTDParams = isset($conf['c.']['TDParams.']) ? $this->cObj->stdWrap($conf['c.']['TDParams'], $conf['c.']['TDParams.']) : $conf['c.']['TDParams'];
|
||||
$controlTable->contentTDparams = isset($contentTDParams) ? $contentTDParams : 'valign="top"';
|
||||
}
|
||||
if (is_array($conf['lm.'])) {
|
||||
$controlTable->lm = $this->cObj->cObjGet($conf['lm.'], 'lm.');
|
||||
$lmTDParams = isset($conf['lm.']['TDParams.']) ? $this->cObj->stdWrap($conf['lm.']['TDParams'], $conf['lm.']['TDParams.']) : $conf['lm.']['TDParams'];
|
||||
$controlTable->lmTDparams = isset($lmTDParams) ? $lmTDParams : 'valign="top"';
|
||||
}
|
||||
if (is_array($conf['tm.'])) {
|
||||
$controlTable->tm = $this->cObj->cObjGet($conf['tm.'], 'tm.');
|
||||
$tmTDParams = isset($conf['tm.']['TDParams.']) ? $this->cObj->stdWrap($conf['tm.']['TDParams'], $conf['tm.']['TDParams.']) : $conf['tm.']['TDParams'];
|
||||
$controlTable->tmTDparams = isset($tmTDParams) ? $tmTDParams : 'valign="top"';
|
||||
}
|
||||
if (is_array($conf['rm.'])) {
|
||||
$controlTable->rm = $this->cObj->cObjGet($conf['rm.'], 'rm.');
|
||||
$rmTDParams = isset($conf['rm.']['TDParams.']) ? $this->cObj->stdWrap($conf['rm.']['TDParams'], $conf['rm.']['TDParams.']) : $conf['rm.']['TDParams'];
|
||||
$controlTable->rmTDparams = isset($rmTDParams) ? $rmTDParams : 'valign="top"';
|
||||
}
|
||||
if (is_array($conf['bm.'])) {
|
||||
$controlTable->bm = $this->cObj->cObjGet($conf['bm.'], 'bm.');
|
||||
$bmTDParams = isset($conf['bm.']['TDParams.']) ? $this->cObj->stdWrap($conf['bm.']['TDParams'], $conf['bm.']['TDParams.']) : $conf['bm.']['TDParams'];
|
||||
$controlTable->bmTDparams = isset($bmTDParams) ? $bmTDParams : 'valign="top"';
|
||||
}
|
||||
$conf['offset'] = isset($conf['offset.']) ? $this->cObj->stdWrap($conf['offset'], $conf['offset.']) : $conf['offset'];
|
||||
$conf['cMargins'] = isset($conf['cMargins.']) ? $this->cObj->stdWrap($conf['cMargins'], $conf['cMargins.']) : $conf['cMargins'];
|
||||
$theValue = $controlTable->start($conf['offset'], $conf['cMargins']);
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$theValue = $this->cObj->stdWrap($theValue, $conf['stdWrap.']);
|
||||
}
|
||||
return $theValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,661 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Contains FORM class object.
|
||||
*/
|
||||
class FormContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* Rendering the cObject, FORM
|
||||
*
|
||||
* Note on $formData:
|
||||
* In the optional $formData array each entry represents a line in the ordinary setup.
|
||||
* In those entries each entry (0,1,2...) represents a space normally divided by the '|' line.
|
||||
*
|
||||
* $formData [] = array('Name:', 'name=input, 25 ', 'Default value....');
|
||||
* $formData [] = array('Email:', 'email=input, 25 ', 'Default value for email....');
|
||||
*
|
||||
* - corresponds to the $conf['data'] value being :
|
||||
* Name:|name=input, 25 |Default value....||Email:|email=input, 25 |Default value for email....
|
||||
*
|
||||
* If $formData is an array the value of $conf['data'] is ignored.
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @param array $formData Alternative formdata overriding whatever comes from TypoScript
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array(), $formData = '')
|
||||
{
|
||||
$content = '';
|
||||
if (is_array($formData)) {
|
||||
$dataArray = $formData;
|
||||
} else {
|
||||
$data = isset($conf['data.']) ? $this->cObj->stdWrap($conf['data'], $conf['data.']) : $conf['data'];
|
||||
// Clearing dataArr
|
||||
$dataArray = array();
|
||||
// Getting the original config
|
||||
if (trim($data)) {
|
||||
$data = str_replace(LF, '||', $data);
|
||||
$dataArray = explode('||', $data);
|
||||
}
|
||||
// Adding the new dataArray config form:
|
||||
if (is_array($conf['dataArray.'])) {
|
||||
// dataArray is supplied
|
||||
$sortedKeyArray = \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList($conf['dataArray.'], true);
|
||||
foreach ($sortedKeyArray as $theKey) {
|
||||
$singleKeyArray = $conf['dataArray.'][$theKey . '.'];
|
||||
if (is_array($singleKeyArray)) {
|
||||
$temp = array();
|
||||
$label = isset($singleKeyArray['label.']) ? $this->cObj->stdWrap($singleKeyArray['label'], $singleKeyArray['label.']) : $singleKeyArray['label'];
|
||||
list($temp[0]) = explode('|', $label);
|
||||
$type = isset($singleKeyArray['type.']) ? $this->cObj->stdWrap($singleKeyArray['type'], $singleKeyArray['type.']) : $singleKeyArray['type'];
|
||||
list($temp[1]) = explode('|', $type);
|
||||
$required = isset($singleKeyArray['required.']) ? $this->cObj->stdWrap($singleKeyArray['required'], $singleKeyArray['required.']) : $singleKeyArray['required'];
|
||||
if ($required) {
|
||||
$temp[1] = '*' . $temp[1];
|
||||
}
|
||||
$singleValue = isset($singleKeyArray['value.']) ? $this->cObj->stdWrap($singleKeyArray['value'], $singleKeyArray['value.']) : $singleKeyArray['value'];
|
||||
list($temp[2]) = explode('|', $singleValue);
|
||||
// If value array is set, then implode those values.
|
||||
if (is_array($singleKeyArray['valueArray.'])) {
|
||||
$temp_accumulated = array();
|
||||
foreach ($singleKeyArray['valueArray.'] as $singleKey => $singleKey_valueArray) {
|
||||
if (is_array($singleKey_valueArray) && (int)$singleKey . '.' === (string)$singleKey) {
|
||||
$temp_valueArray = array();
|
||||
$valueArrayLabel = isset($singleKey_valueArray['label.']) ? $this->cObj->stdWrap($singleKey_valueArray['label'], $singleKey_valueArray['label.']) : $singleKey_valueArray['label'];
|
||||
list($temp_valueArray[0]) = explode('=', $valueArrayLabel);
|
||||
$selected = isset($singleKey_valueArray['selected.']) ? $this->cObj->stdWrap($singleKey_valueArray['selected'], $singleKey_valueArray['selected.']) : $singleKey_valueArray['selected'];
|
||||
if ($selected) {
|
||||
$temp_valueArray[0] = '*' . $temp_valueArray[0];
|
||||
}
|
||||
$singleKeyValue = isset($singleKey_valueArray['value.']) ? $this->cObj->stdWrap($singleKey_valueArray['value'], $singleKey_valueArray['value.']) : $singleKey_valueArray['value'];
|
||||
list($temp_valueArray[1]) = explode(',', $singleKeyValue);
|
||||
}
|
||||
$temp_accumulated[] = implode('=', $temp_valueArray);
|
||||
}
|
||||
$temp[2] = implode(',', $temp_accumulated);
|
||||
}
|
||||
$specialEval = isset($singleKeyArray['specialEval.']) ? $this->cObj->stdWrap($singleKeyArray['specialEval'], $singleKeyArray['specialEval.']) : $singleKeyArray['specialEval'];
|
||||
list($temp[3]) = explode('|', $specialEval);
|
||||
// Adding the form entry to the dataArray
|
||||
$dataArray[] = implode('|', $temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$attachmentCounter = '';
|
||||
$hiddenfields = '';
|
||||
$fieldlist = array();
|
||||
$propertyOverride = array();
|
||||
$fieldname_hashArray = array();
|
||||
$counter = 0;
|
||||
$xhtmlStrict = GeneralUtility::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype);
|
||||
// Formname
|
||||
$formName = isset($conf['formName.']) ? $this->cObj->stdWrap($conf['formName'], $conf['formName.']) : $conf['formName'];
|
||||
$formName = $this->cleanFormName($formName);
|
||||
$formName = $GLOBALS['TSFE']->getUniqueId($formName);
|
||||
|
||||
$fieldPrefix = isset($conf['fieldPrefix.']) ? $this->cObj->stdWrap($conf['fieldPrefix'], $conf['fieldPrefix.']) : $conf['fieldPrefix'];
|
||||
if (isset($conf['fieldPrefix']) || isset($conf['fieldPrefix.'])) {
|
||||
if ($fieldPrefix) {
|
||||
$prefix = $this->cleanFormName($fieldPrefix);
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
} else {
|
||||
$prefix = $formName;
|
||||
}
|
||||
foreach ($dataArray as $dataValue) {
|
||||
$counter++;
|
||||
$confData = array();
|
||||
if (is_array($formData)) {
|
||||
$parts = $dataValue;
|
||||
// TRUE...
|
||||
$dataValue = 1;
|
||||
} else {
|
||||
$dataValue = trim($dataValue);
|
||||
$parts = explode('|', $dataValue);
|
||||
}
|
||||
if ($dataValue && strcspn($dataValue, '#/')) {
|
||||
// label:
|
||||
$confData['label'] = GeneralUtility::removeXSS(trim($parts[0]));
|
||||
// field:
|
||||
$fParts = explode(',', $parts[1]);
|
||||
$fParts[0] = trim($fParts[0]);
|
||||
if ($fParts[0][0] === '*') {
|
||||
$confData['required'] = 1;
|
||||
$fParts[0] = substr($fParts[0], 1);
|
||||
}
|
||||
$typeParts = explode('=', $fParts[0]);
|
||||
$confData['type'] = trim(strtolower(end($typeParts)));
|
||||
if (count($typeParts) === 1) {
|
||||
$confData['fieldname'] = $this->cleanFormName($parts[0]);
|
||||
if (strtolower(preg_replace('/[^[:alnum:]]/', '', $confData['fieldname'])) == 'email') {
|
||||
$confData['fieldname'] = 'email';
|
||||
}
|
||||
// Duplicate fieldnames resolved
|
||||
if (isset($fieldname_hashArray[md5($confData['fieldname'])])) {
|
||||
$confData['fieldname'] .= '_' . $counter;
|
||||
}
|
||||
$fieldname_hashArray[md5($confData['fieldname'])] = $confData['fieldname'];
|
||||
// Attachment names...
|
||||
if ($confData['type'] == 'file') {
|
||||
$confData['fieldname'] = 'attachment' . $attachmentCounter;
|
||||
$attachmentCounter = (int)$attachmentCounter + 1;
|
||||
}
|
||||
} else {
|
||||
$confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
|
||||
}
|
||||
$confData['fieldname'] = htmlspecialchars($confData['fieldname']);
|
||||
$fieldCode = '';
|
||||
$wrapFieldName = isset($conf['wrapFieldName']) ? $this->cObj->stdWrap($conf['wrapFieldName'], $conf['wrapFieldName.']) : $conf['wrapFieldName'];
|
||||
if ($wrapFieldName) {
|
||||
$confData['fieldname'] = $this->cObj->wrap($confData['fieldname'], $wrapFieldName);
|
||||
}
|
||||
// Set field name as current:
|
||||
$this->cObj->setCurrentVal($confData['fieldname']);
|
||||
// Additional parameters
|
||||
if (trim($confData['type'])) {
|
||||
if (isset($conf['params.'][$confData['type']])) {
|
||||
$addParams = isset($conf['params.'][$confData['type'] . '.']) ? trim($this->cObj->stdWrap($conf['params.'][$confData['type']], $conf['params.'][$confData['type'] . '.'])) : trim($conf['params.'][$confData['type']]);
|
||||
} else {
|
||||
$addParams = isset($conf['params.']) ? trim($this->cObj->stdWrap($conf['params'], $conf['params.'])) : trim($conf['params']);
|
||||
}
|
||||
if ((string)$addParams !== '') {
|
||||
$addParams = ' ' . $addParams;
|
||||
}
|
||||
} else {
|
||||
$addParams = '';
|
||||
}
|
||||
$dontMd5FieldNames = isset($conf['dontMd5FieldNames.']) ? $this->cObj->stdWrap($conf['dontMd5FieldNames'], $conf['dontMd5FieldNames.']) : $conf['dontMd5FieldNames'];
|
||||
if ($dontMd5FieldNames) {
|
||||
$fName = $confData['fieldname'];
|
||||
} else {
|
||||
$fName = md5($confData['fieldname']);
|
||||
}
|
||||
// Accessibility: Set id = fieldname attribute:
|
||||
$accessibility = isset($conf['accessibility.']) ? $this->cObj->stdWrap($conf['accessibility'], $conf['accessibility.']) : $conf['accessibility'];
|
||||
if ($accessibility || $xhtmlStrict) {
|
||||
$elementIdAttribute = ' id="' . $prefix . $fName . '"';
|
||||
} else {
|
||||
$elementIdAttribute = '';
|
||||
}
|
||||
// Create form field based on configuration/type:
|
||||
switch ($confData['type']) {
|
||||
case 'textarea':
|
||||
$cols = trim($fParts[1]) ? (int)$fParts[1] : 20;
|
||||
$compensateFieldWidth = isset($conf['compensateFieldWidth.']) ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.']) : $conf['compensateFieldWidth'];
|
||||
$compWidth = doubleval($compensateFieldWidth ? $compensateFieldWidth : $GLOBALS['TSFE']->compensateFieldWidth);
|
||||
$compWidth = $compWidth ? $compWidth : 1;
|
||||
$cols = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($cols * $compWidth, 1, 120);
|
||||
$rows = trim($fParts[2]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[2], 1, 30) : 5;
|
||||
$wrap = trim($fParts[3]);
|
||||
$noWrapAttr = isset($conf['noWrapAttr.']) ? $this->cObj->stdWrap($conf['noWrapAttr'], $conf['noWrapAttr.']) : $conf['noWrapAttr'];
|
||||
if ($noWrapAttr || $wrap === 'disabled') {
|
||||
$wrap = '';
|
||||
} else {
|
||||
$wrap = $wrap ? ' wrap="' . $wrap . '"' : ' wrap="virtual"';
|
||||
}
|
||||
$noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
|
||||
$default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], str_replace('\\n', LF, trim($parts[2])));
|
||||
$fieldCode = sprintf('<textarea name="%s"%s cols="%s" rows="%s"%s%s>%s</textarea>', $confData['fieldname'], $elementIdAttribute, $cols, $rows, $wrap, $addParams, htmlspecialchars($default));
|
||||
break;
|
||||
case 'input':
|
||||
|
||||
case 'password':
|
||||
$size = trim($fParts[1]) ? (int)$fParts[1] : 20;
|
||||
$compensateFieldWidth = isset($conf['compensateFieldWidth.']) ? $this->cObj->stdWrap($conf['compensateFieldWidth'], $conf['compensateFieldWidth.']) : $conf['compensateFieldWidth'];
|
||||
$compWidth = doubleval($compensateFieldWidth ? $compensateFieldWidth : $GLOBALS['TSFE']->compensateFieldWidth);
|
||||
$compWidth = $compWidth ? $compWidth : 1;
|
||||
$size = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($size * $compWidth, 1, 120);
|
||||
$noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
|
||||
$default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], trim($parts[2]));
|
||||
if ($confData['type'] == 'password') {
|
||||
$default = '';
|
||||
}
|
||||
$max = trim($fParts[2]) ? ' maxlength="' . \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[2], 1, 1000) . '"' : '';
|
||||
$theType = $confData['type'] == 'input' ? 'text' : 'password';
|
||||
$fieldCode = sprintf('<input type="%s" name="%s"%s size="%s"%s value="%s"%s />', $theType, $confData['fieldname'], $elementIdAttribute, $size, $max, htmlspecialchars($default), $addParams);
|
||||
break;
|
||||
case 'file':
|
||||
$size = trim($fParts[1]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[1], 1, 60) : 20;
|
||||
$fieldCode = sprintf('<input type="file" name="%s"%s size="%s"%s />', $confData['fieldname'], $elementIdAttribute, $size, $addParams);
|
||||
break;
|
||||
case 'check':
|
||||
// alternative default value:
|
||||
$noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
|
||||
$default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], trim($parts[2]));
|
||||
$checked = $default ? ' checked="checked"' : '';
|
||||
$fieldCode = sprintf('<input type="checkbox" value="%s" name="%s"%s%s%s />', 1, $confData['fieldname'], $elementIdAttribute, $checked, $addParams);
|
||||
break;
|
||||
case 'select':
|
||||
$option = '';
|
||||
$valueParts = explode(',', $parts[2]);
|
||||
// size
|
||||
if (strtolower(trim($fParts[1])) == 'auto') {
|
||||
$fParts[1] = count($valueParts);
|
||||
}
|
||||
// Auto size set here. Max 20
|
||||
$size = trim($fParts[1]) ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fParts[1], 1, 20) : 1;
|
||||
// multiple
|
||||
$multiple = strtolower(trim($fParts[2])) == 'm' ? ' multiple="multiple"' : '';
|
||||
// Where the items will be
|
||||
$items = array();
|
||||
//RTF
|
||||
$defaults = array();
|
||||
$pCount = count($valueParts);
|
||||
for ($a = 0; $a < $pCount; $a++) {
|
||||
$valueParts[$a] = trim($valueParts[$a]);
|
||||
// Finding default value
|
||||
if ($valueParts[$a][0] === '*') {
|
||||
$sel = 'selected';
|
||||
$valueParts[$a] = substr($valueParts[$a], 1);
|
||||
} else {
|
||||
$sel = '';
|
||||
}
|
||||
// Get value/label
|
||||
$subParts = explode('=', $valueParts[$a]);
|
||||
// Sets the value
|
||||
$subParts[1] = isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0]);
|
||||
// Adds the value/label pair to the items-array
|
||||
$items[] = $subParts;
|
||||
if ($sel) {
|
||||
$defaults[] = $subParts[1];
|
||||
}
|
||||
}
|
||||
// alternative default value:
|
||||
$noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
|
||||
$default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], $defaults);
|
||||
if (!is_array($default)) {
|
||||
$defaults = array();
|
||||
$defaults[] = $default;
|
||||
} else {
|
||||
$defaults = $default;
|
||||
}
|
||||
// Create the select-box:
|
||||
$iCount = count($items);
|
||||
for ($a = 0; $a < $iCount; $a++) {
|
||||
$option .= '<option value="' . $items[$a][1] . '"' . (in_array($items[$a][1], $defaults) ? ' selected="selected"' : '') . '>' . trim($items[$a][0]) . '</option>';
|
||||
}
|
||||
if ($multiple) {
|
||||
// The fieldname must be prepended '[]' if multiple select. And the reason why it's prepended is, because the required-field list later must also have [] prepended.
|
||||
$confData['fieldname'] .= '[]';
|
||||
}
|
||||
$fieldCode = sprintf('<select name="%s"%s size="%s"%s%s>%s</select>', $confData['fieldname'], $elementIdAttribute, $size, $multiple, $addParams, $option);
|
||||
//RTF
|
||||
break;
|
||||
case 'radio':
|
||||
$option = '';
|
||||
$valueParts = explode(',', $parts[2]);
|
||||
// Where the items will be
|
||||
$items = array();
|
||||
$default = '';
|
||||
$pCount = count($valueParts);
|
||||
for ($a = 0; $a < $pCount; $a++) {
|
||||
$valueParts[$a] = trim($valueParts[$a]);
|
||||
if ($valueParts[$a][0] === '*') {
|
||||
$sel = 'checked';
|
||||
$valueParts[$a] = substr($valueParts[$a], 1);
|
||||
} else {
|
||||
$sel = '';
|
||||
}
|
||||
// Get value/label
|
||||
$subParts = explode('=', $valueParts[$a]);
|
||||
// Sets the value
|
||||
$subParts[1] = isset($subParts[1]) ? trim($subParts[1]) : trim($subParts[0]);
|
||||
// Adds the value/label pair to the items-array
|
||||
$items[] = $subParts;
|
||||
if ($sel) {
|
||||
$default = $subParts[1];
|
||||
}
|
||||
}
|
||||
// alternative default value:
|
||||
$noValueInsert = isset($conf['noValueInsert.']) ? $this->cObj->stdWrap($conf['noValueInsert'], $conf['noValueInsert.']) : $conf['noValueInsert'];
|
||||
$default = $this->getFieldDefaultValue($noValueInsert, $confData['fieldname'], $default);
|
||||
// Create the select-box:
|
||||
$iCount = count($items);
|
||||
for ($a = 0; $a < $iCount; $a++) {
|
||||
$optionParts = '';
|
||||
$radioId = $prefix . $fName . $this->cleanFormName($items[$a][0]);
|
||||
if ($accessibility) {
|
||||
$radioLabelIdAttribute = ' id="' . $radioId . '"';
|
||||
} else {
|
||||
$radioLabelIdAttribute = '';
|
||||
}
|
||||
$optionParts .= '<input type="radio" name="' . $confData['fieldname'] . '"' . $radioLabelIdAttribute . ' value="' . $items[$a][1] . '"' . ((string)$items[$a][1] === (string)$default ? ' checked="checked"' : '') . $addParams . ' />';
|
||||
if ($accessibility) {
|
||||
$label = isset($conf['radioWrap.']) ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.']) : trim($items[$a][0]);
|
||||
$optionParts .= '<label for="' . $radioId . '">' . $label . '</label>';
|
||||
} else {
|
||||
$optionParts .= isset($conf['radioWrap.']) ? $this->cObj->stdWrap(trim($items[$a][0]), $conf['radioWrap.']) : trim($items[$a][0]);
|
||||
}
|
||||
$option .= isset($conf['radioInputWrap.']) ? $this->cObj->stdWrap($optionParts, $conf['radioInputWrap.']) : $optionParts;
|
||||
}
|
||||
if ($accessibility) {
|
||||
$accessibilityWrap = isset($conf['radioWrap.']['accessibilityWrap.']) ? $this->cObj->stdWrap($conf['radioWrap.']['accessibilityWrap'], $conf['radioWrap.']['accessibilityWrap.']) : $conf['radioWrap.']['accessibilityWrap'];
|
||||
if ($accessibilityWrap) {
|
||||
$search = array(
|
||||
'###RADIO_FIELD_ID###',
|
||||
'###RADIO_GROUP_LABEL###'
|
||||
);
|
||||
$replace = array(
|
||||
$elementIdAttribute,
|
||||
$confData['label']
|
||||
);
|
||||
$accessibilityWrap = str_replace($search, $replace, $accessibilityWrap);
|
||||
$option = $this->cObj->wrap($option, $accessibilityWrap);
|
||||
}
|
||||
}
|
||||
$fieldCode = $option;
|
||||
break;
|
||||
case 'hidden':
|
||||
$value = trim($parts[2]);
|
||||
// If this form includes an auto responder message, include a HMAC checksum field
|
||||
// in order to verify potential abuse of this feature.
|
||||
if ($value !== '') {
|
||||
if (GeneralUtility::inList($confData['fieldname'], 'auto_respond_msg')) {
|
||||
$hmacChecksum = GeneralUtility::hmac($value, 'content_form');
|
||||
$hiddenfields .= sprintf('<input type="hidden" name="auto_respond_checksum" id="%sauto_respond_checksum" value="%s" />', $prefix, $hmacChecksum);
|
||||
}
|
||||
if (GeneralUtility::inList('recipient_copy,recipient', $confData['fieldname']) && $GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
|
||||
break;
|
||||
}
|
||||
if (GeneralUtility::inList('recipient_copy,recipient', $confData['fieldname'])) {
|
||||
$value = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($value);
|
||||
}
|
||||
}
|
||||
$hiddenfields .= sprintf('<input type="hidden" name="%s"%s value="%s" />', $confData['fieldname'], $elementIdAttribute, htmlspecialchars($value));
|
||||
break;
|
||||
case 'property':
|
||||
if (GeneralUtility::inList('type,locationData,goodMess,badMess,emailMess', $confData['fieldname'])) {
|
||||
$value = trim($parts[2]);
|
||||
$propertyOverride[$confData['fieldname']] = $value;
|
||||
$conf[$confData['fieldname']] = $value;
|
||||
}
|
||||
break;
|
||||
case 'submit':
|
||||
$value = trim($parts[2]);
|
||||
if ($conf['image.']) {
|
||||
$this->cObj->data[$this->cObj->currentValKey] = $value;
|
||||
$image = $this->cObj->cObjGetSingle('IMG_RESOURCE', $conf['image.']);
|
||||
$params = $conf['image.']['params'] ? ' ' . $conf['image.']['params'] : '';
|
||||
$params .= $this->cObj->getAltParam($conf['image.'], false);
|
||||
$params .= $addParams;
|
||||
} else {
|
||||
$image = '';
|
||||
}
|
||||
if ($image) {
|
||||
$fieldCode = sprintf('<input type="image" name="%s"%s src="%s"%s />', $confData['fieldname'], $elementIdAttribute, $image, $params);
|
||||
} else {
|
||||
$fieldCode = sprintf('<input type="submit" name="%s"%s value="%s"%s />', $confData['fieldname'], $elementIdAttribute, htmlspecialchars($value, ENT_COMPAT, 'UTF-8', false), $addParams);
|
||||
}
|
||||
break;
|
||||
case 'reset':
|
||||
$value = trim($parts[2]);
|
||||
$fieldCode = sprintf('<input type="reset" name="%s"%s value="%s"%s />', $confData['fieldname'], $elementIdAttribute, htmlspecialchars($value, ENT_COMPAT, 'UTF-8', false), $addParams);
|
||||
break;
|
||||
case 'label':
|
||||
$fieldCode = nl2br(htmlspecialchars(trim($parts[2])));
|
||||
break;
|
||||
default:
|
||||
$confData['type'] = 'comment';
|
||||
$fieldCode = trim($parts[2]) . ' ';
|
||||
}
|
||||
if ($fieldCode) {
|
||||
// Checking for special evaluation modes:
|
||||
if (trim($parts[3]) !== '' && GeneralUtility::inList('textarea,input,password', $confData['type'])) {
|
||||
$modeParameters = GeneralUtility::trimExplode(':', $parts[3]);
|
||||
} else {
|
||||
$modeParameters = array();
|
||||
}
|
||||
// Adding evaluation based on settings:
|
||||
switch ((string)$modeParameters[0]) {
|
||||
case 'EREG':
|
||||
$fieldlist[] = '_EREG';
|
||||
$fieldlist[] = $modeParameters[1];
|
||||
$fieldlist[] = $modeParameters[2];
|
||||
$fieldlist[] = $confData['fieldname'];
|
||||
$fieldlist[] = $confData['label'];
|
||||
// Setting this so "required" layout is used.
|
||||
$confData['required'] = 1;
|
||||
break;
|
||||
case 'EMAIL':
|
||||
$fieldlist[] = '_EMAIL';
|
||||
$fieldlist[] = $confData['fieldname'];
|
||||
$fieldlist[] = $confData['label'];
|
||||
// Setting this so "required" layout is used.
|
||||
$confData['required'] = 1;
|
||||
break;
|
||||
default:
|
||||
if ($confData['required']) {
|
||||
$fieldlist[] = $confData['fieldname'];
|
||||
$fieldlist[] = $confData['label'];
|
||||
}
|
||||
}
|
||||
// Field:
|
||||
$fieldLabel = $confData['label'];
|
||||
if ($accessibility && trim($fieldLabel) && !preg_match('/^(label|hidden|comment)$/', $confData['type'])) {
|
||||
$fieldLabel = '<label for="' . $prefix . $fName . '">' . $fieldLabel . '</label>';
|
||||
}
|
||||
// Getting template code:
|
||||
if (isset($conf['fieldWrap.'])) {
|
||||
$fieldCode = $this->cObj->stdWrap($fieldCode, $conf['fieldWrap.']);
|
||||
}
|
||||
$labelCode = isset($conf['labelWrap.']) ? $this->cObj->stdWrap($fieldLabel, $conf['labelWrap.']) : $fieldLabel;
|
||||
$commentCode = isset($conf['commentWrap.']) ? $this->cObj->stdWrap($confData['label'], $conf['commentWrap.']) : $confData['label'];
|
||||
$result = $conf['layout'];
|
||||
$req = isset($conf['REQ.']) ? $this->cObj->stdWrap($conf['REQ'], $conf['REQ.']) : $conf['REQ'];
|
||||
if ($req && $confData['required']) {
|
||||
if (isset($conf['REQ.']['fieldWrap.'])) {
|
||||
$fieldCode = $this->cObj->stdWrap($fieldCode, $conf['REQ.']['fieldWrap.']);
|
||||
}
|
||||
if (isset($conf['REQ.']['labelWrap.'])) {
|
||||
$labelCode = $this->cObj->stdWrap($fieldLabel, $conf['REQ.']['labelWrap.']);
|
||||
}
|
||||
$reqLayout = isset($conf['REQ.']['layout.']) ? $this->cObj->stdWrap($conf['REQ.']['layout'], $conf['REQ.']['layout.']) : $conf['REQ.']['layout'];
|
||||
if ($reqLayout) {
|
||||
$result = $reqLayout;
|
||||
}
|
||||
}
|
||||
if ($confData['type'] == 'comment') {
|
||||
$commentLayout = isset($conf['COMMENT.']['layout.']) ? $this->cObj->stdWrap($conf['COMMENT.']['layout'], $conf['COMMENT.']['layout.']) : $conf['COMMENT.']['layout'];
|
||||
if ($commentLayout) {
|
||||
$result = $commentLayout;
|
||||
}
|
||||
}
|
||||
if ($confData['type'] == 'check') {
|
||||
$checkLayout = isset($conf['CHECK.']['layout.']) ? $this->cObj->stdWrap($conf['CHECK.']['layout'], $conf['CHECK.']['layout.']) : $conf['CHECK.']['layout'];
|
||||
if ($checkLayout) {
|
||||
$result = $checkLayout;
|
||||
}
|
||||
}
|
||||
if ($confData['type'] == 'radio') {
|
||||
$radioLayout = isset($conf['RADIO.']['layout.']) ? $this->cObj->stdWrap($conf['RADIO.']['layout'], $conf['RADIO.']['layout.']) : $conf['RADIO.']['layout'];
|
||||
if ($radioLayout) {
|
||||
$result = $radioLayout;
|
||||
}
|
||||
}
|
||||
if ($confData['type'] == 'label') {
|
||||
$labelLayout = isset($conf['LABEL.']['layout.']) ? $this->cObj->stdWrap($conf['LABEL.']['layout'], $conf['LABEL.']['layout.']) : $conf['LABEL.']['layout'];
|
||||
if ($labelLayout) {
|
||||
$result = $labelLayout;
|
||||
}
|
||||
}
|
||||
//RTF
|
||||
$content .= str_replace(
|
||||
array(
|
||||
'###FIELD###',
|
||||
'###LABEL###',
|
||||
'###COMMENT###'
|
||||
),
|
||||
array(
|
||||
$fieldCode,
|
||||
$labelCode,
|
||||
$commentCode
|
||||
),
|
||||
$result
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
|
||||
}
|
||||
// Redirect (external: where to go afterwards. internal: where to submit to)
|
||||
$theRedirect = isset($conf['redirect.']) ? $this->cObj->stdWrap($conf['redirect'], $conf['redirect.']) : $conf['redirect'];
|
||||
// redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
|
||||
$target = isset($conf['target.']) ? $this->cObj->stdWrap($conf['target'], $conf['target.']) : $conf['target'];
|
||||
// redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
|
||||
$noCache = isset($conf['no_cache.']) ? $this->cObj->stdWrap($conf['no_cache'], $conf['no_cache.']) : $conf['no_cache'];
|
||||
// redirect should be set to the page to redirect to after an external script has been used. If internal scripts is used, and if no 'type' is set that dictates otherwise, redirect is used as the url to jump to as long as it's an integer (page)
|
||||
$page = $GLOBALS['TSFE']->page;
|
||||
// Internal: Just submit to current page
|
||||
if (!$theRedirect) {
|
||||
$LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, 'index.php', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
|
||||
} elseif (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($theRedirect)) {
|
||||
// Internal: Submit to page with ID $theRedirect
|
||||
$page = $GLOBALS['TSFE']->sys_page->getPage_noCheck($theRedirect);
|
||||
$LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, 'index.php', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
|
||||
} else {
|
||||
// External URL, redirect-hidden field is rendered!
|
||||
$LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, '', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
|
||||
$LD['totalURL'] = $theRedirect;
|
||||
$hiddenfields .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($LD['totalURL']) . '" />';
|
||||
}
|
||||
// Formtype (where to submit to!):
|
||||
if ($propertyOverride['type']) {
|
||||
$formtype = $propertyOverride['type'];
|
||||
} else {
|
||||
$formtype = isset($conf['type.']) ? $this->cObj->stdWrap($conf['type'], $conf['type.']) : $conf['type'];
|
||||
}
|
||||
// Submit to a specific page
|
||||
if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($formtype)) {
|
||||
$page = $GLOBALS['TSFE']->sys_page->getPage_noCheck($formtype);
|
||||
$LD_A = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $noCache, '', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
|
||||
$action = $LD_A['totalURL'];
|
||||
} elseif ($formtype) {
|
||||
// Submit to external script
|
||||
$LD_A = $LD;
|
||||
$action = $formtype;
|
||||
} elseif (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($theRedirect)) {
|
||||
$LD_A = $LD;
|
||||
$action = $LD_A['totalURL'];
|
||||
} else {
|
||||
// Submit to "nothing" - which is current page
|
||||
$LD_A = $GLOBALS['TSFE']->tmpl->linkData($GLOBALS['TSFE']->page, $target, $noCache, '', '', $this->cObj->getClosestMPvalueForPage($page['uid']));
|
||||
$action = $LD_A['totalURL'];
|
||||
}
|
||||
// Recipient:
|
||||
$theEmail = isset($conf['recipient.']) ? $this->cObj->stdWrap($conf['recipient'], $conf['recipient.']) : $conf['recipient'];
|
||||
if ($theEmail && !$GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
|
||||
$theEmail = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($theEmail);
|
||||
$hiddenfields .= '<input type="hidden" name="recipient" value="' . htmlspecialchars($theEmail) . '" />';
|
||||
}
|
||||
// location data:
|
||||
$location = isset($conf['locationData.']) ? $this->cObj->stdWrap($conf['locationData'], $conf['locationData.']) : $conf['locationData'];
|
||||
if ($location) {
|
||||
if ($location == 'HTTP_POST_VARS' && isset($_POST['locationData'])) {
|
||||
$locationData = GeneralUtility::_POST('locationData');
|
||||
} else {
|
||||
// locationData is [the page id]:[tablename]:[uid of record]. Indicates on which page the record (from tablename with uid) is shown. Used to check access.
|
||||
if (isset($this->data['_LOCALIZED_UID'])) {
|
||||
$locationData = $GLOBALS['TSFE']->id . ':' . str_replace($this->data['uid'], $this->data['_LOCALIZED_UID'], $this->cObj->currentRecord);
|
||||
} else {
|
||||
$locationData = $GLOBALS['TSFE']->id . ':' . $this->cObj->currentRecord;
|
||||
}
|
||||
}
|
||||
$hiddenfields .= '<input type="hidden" name="locationData" value="' . htmlspecialchars($locationData) . '" />';
|
||||
}
|
||||
// Hidden fields:
|
||||
if (is_array($conf['hiddenFields.'])) {
|
||||
foreach ($conf['hiddenFields.'] as $hF_key => $hF_conf) {
|
||||
if (substr($hF_key, -1) != '.') {
|
||||
$hF_value = $this->cObj->cObjGetSingle($hF_conf, $conf['hiddenFields.'][$hF_key . '.'], 'hiddenfields');
|
||||
if ((string)$hF_value !== '' && GeneralUtility::inList('recipient_copy,recipient', $hF_key)) {
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['FE']['secureFormmail']) {
|
||||
continue;
|
||||
}
|
||||
$hF_value = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($hF_value);
|
||||
}
|
||||
$hiddenfields .= '<input type="hidden" name="' . $hF_key . '" value="' . htmlspecialchars($hF_value) . '" />';
|
||||
}
|
||||
}
|
||||
}
|
||||
// Wrap all hidden fields in a div tag (see http://forge.typo3.org/issues/14491)
|
||||
$hiddenfields = isset($conf['hiddenFields.']['stdWrap.']) ? $this->cObj->stdWrap($hiddenfields, $conf['hiddenFields.']['stdWrap.']) : '<div style="display:none;">' . $hiddenfields . '</div>';
|
||||
if ($conf['REQ']) {
|
||||
$goodMess = isset($conf['goodMess.']) ? $this->cObj->stdWrap($conf['goodMess'], $conf['goodMess.']) : $conf['goodMess'];
|
||||
$badMess = isset($conf['badMess.']) ? $this->cObj->stdWrap($conf['badMess'], $conf['badMess.']) : $conf['badMess'];
|
||||
$emailMess = isset($conf['emailMess.']) ? $this->cObj->stdWrap($conf['emailMess'], $conf['emailMess.']) : $conf['emailMess'];
|
||||
$validateForm = ' onsubmit="return validateForm(' . GeneralUtility::quoteJSvalue($formName) . ',' . GeneralUtility::quoteJSvalue(implode(',', $fieldlist)) . ',' . GeneralUtility::quoteJSvalue($goodMess) . ',' . GeneralUtility::quoteJSvalue($badMess) . ',' . GeneralUtility::quoteJSvalue($emailMess) . ')"';
|
||||
$GLOBALS['TSFE']->additionalHeaderData['JSFormValidate'] = '<script type="text/javascript" src="' . GeneralUtility::createVersionNumberedFilename(($GLOBALS['TSFE']->absRefPrefix . 'typo3/sysext/compatibility6/Resources/Public/JavaScript/jsfunc.validateform.js')) . '"></script>';
|
||||
} else {
|
||||
$validateForm = '';
|
||||
}
|
||||
// Create form tag:
|
||||
$theTarget = $theRedirect ? $LD['target'] : $LD_A['target'];
|
||||
$method = isset($conf['method.']) ? $this->cObj->stdWrap($conf['method'], $conf['method.']) : $conf['method'];
|
||||
$content = array(
|
||||
'<form' . ' action="' . htmlspecialchars($action) . '"' . ' id="' . $formName . '"' . ($xhtmlStrict ? '' : ' name="' . $formName . '"') . ' enctype="multipart/form-data"' . ' method="' . ($method ? $method : 'post') . '"' . ($theTarget ? ' target="' . $theTarget . '"' : '') . $validateForm . '>',
|
||||
$hiddenfields . $content,
|
||||
'</form>'
|
||||
);
|
||||
$arrayReturnMode = isset($conf['arrayReturnMode.']) ? $this->cObj->stdWrap($conf['arrayReturnMode'], $conf['arrayReturnMode.']) : $conf['arrayReturnMode'];
|
||||
if ($arrayReturnMode) {
|
||||
$content['validateForm'] = $validateForm;
|
||||
$content['formname'] = $formName;
|
||||
return $content;
|
||||
} else {
|
||||
return implode('', $content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a default value for a form field in the FORM cObject.
|
||||
* Page CANNOT be cached because that would include the inserted value for the current user.
|
||||
*
|
||||
* @param bool $noValueInsert If noValueInsert OR if the no_cache flag for this page is NOT set, the original default value is returned.
|
||||
* @param string $fieldName The POST var name to get default value for
|
||||
* @param string $defaultVal The current default value
|
||||
* @return string The default value, either from INPUT var or the current default, based on whether caching is enabled or not.
|
||||
*/
|
||||
protected function getFieldDefaultValue($noValueInsert, $fieldName, $defaultVal)
|
||||
{
|
||||
if (!$GLOBALS['TSFE']->no_cache || !isset($_POST[$fieldName]) && !isset($_GET[$fieldName]) || $noValueInsert) {
|
||||
return $defaultVal;
|
||||
} else {
|
||||
return GeneralUtility::_GP($fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes forbidden characters and spaces from name/id attributes in the form tag and formfields
|
||||
*
|
||||
* @param string $name Input string
|
||||
* @return string the cleaned string
|
||||
*/
|
||||
protected function cleanFormName($name)
|
||||
{
|
||||
// Turn data[x][y] into data:x:y:
|
||||
$name = preg_replace('/\\[|\\]\\[?/', ':', trim($name));
|
||||
// Remove illegal chars like _
|
||||
return preg_replace('#[^:a-zA-Z0-9]#', '', $name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains HRULER content object.
|
||||
*/
|
||||
class HorizontalRulerContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* Rendering the cObject, HRULER
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
$lineThickness = isset($conf['lineThickness.']) ? $this->cObj->stdWrap($conf['lineThickness'], $conf['lineThickness.']) : $conf['lineThickness'];
|
||||
$lineThickness = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($lineThickness, 1, 50);
|
||||
$lineColor = isset($conf['lineColor.']) ? $this->cObj->stdWrap($conf['lineColor'], $conf['lineColor.']) : $conf['lineColor'];
|
||||
if (!$lineColor) {
|
||||
$lineColor = 'black';
|
||||
}
|
||||
$spaceBefore = isset($conf['spaceLeft.']) ? (int)$this->cObj->stdWrap($conf['spaceLeft'], $conf['spaceLeft.']) : (int)$conf['spaceLeft'];
|
||||
$spaceAfter = isset($conf['spaceRight.']) ? (int)$this->cObj->stdWrap($conf['spaceRight'], $conf['spaceRight.']) : (int)$conf['spaceRight'];
|
||||
$tableWidth = isset($conf['tableWidth.']) ? (int)$this->cObj->stdWrap($conf['tableWidth'], $conf['tableWidth.']) : (int)$conf['tableWidth'];
|
||||
if (!$tableWidth) {
|
||||
$tableWidth = '99%';
|
||||
}
|
||||
$theValue = '';
|
||||
$theValue .= '<table border="0" cellspacing="0" cellpadding="0"
|
||||
width="' . htmlspecialchars($tableWidth) . '"
|
||||
summary=""><tr>';
|
||||
if ($spaceBefore) {
|
||||
$theValue .= '<td width="1">
|
||||
<span style="width: ' . $spaceBefore . 'px; height: 1px;"></span>
|
||||
</td>';
|
||||
}
|
||||
$theValue .= '<td bgcolor="' . $lineColor . '">
|
||||
<span style="width: 1px; height: ' . $lineThickness . 'px;"></span>
|
||||
</td>';
|
||||
if ($spaceAfter) {
|
||||
$theValue .= '<td width="1">
|
||||
<span style="width: ' . $spaceAfter . 'px; height: 1px;"></span>
|
||||
</td>';
|
||||
}
|
||||
$theValue .= '</tr></table>';
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$theValue = $this->cObj->stdWrap($theValue, $conf['stdWrap.']);
|
||||
}
|
||||
return $theValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,513 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Resource\ResourceFactory;
|
||||
|
||||
/**
|
||||
* Contains IMGTEXT content object.
|
||||
*/
|
||||
class ImageTextContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* @var ResourceFactory
|
||||
*/
|
||||
protected $fileFactory = null;
|
||||
|
||||
/**
|
||||
* Rendering the cObject, IMGTEXT
|
||||
* which is a text w/ image type that works with the image position through tables (pre-CSS styled content-time)
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
$content = '';
|
||||
if (isset($conf['text.'])) {
|
||||
$text = $this->cObj->cObjGet($conf['text.'], 'text.');
|
||||
// this gets the surrounding content
|
||||
$content .= $this->cObj->stdWrap($text, $conf['text.']);
|
||||
}
|
||||
$imgList = isset($conf['imgList.']) ? trim($this->cObj->stdWrap($conf['imgList'], $conf['imgList.'])) : trim($conf['imgList']);
|
||||
if ($imgList) {
|
||||
$imgs = GeneralUtility::trimExplode(',', $imgList, true);
|
||||
$imgStart = isset($conf['imgStart.']) ? (int)$this->cObj->stdWrap($conf['imgStart'], $conf['imgStart.']) : (int)$conf['imgStart'];
|
||||
$imgCount = count($imgs) - $imgStart;
|
||||
$imgMax = isset($conf['imgMax.']) ? (int)$this->cObj->stdWrap($conf['imgMax'], $conf['imgMax.']) : (int)$conf['imgMax'];
|
||||
if ($imgMax) {
|
||||
// Reduces the number of images.
|
||||
$imgCount = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($imgCount, 0, $imgMax);
|
||||
}
|
||||
$imgPath = isset($conf['imgPath.']) ? $this->cObj->stdWrap($conf['imgPath'], $conf['imgPath.']) : $conf['imgPath'];
|
||||
// initialisation
|
||||
$caption = '';
|
||||
$captionArray = array();
|
||||
if (!$conf['captionSplit'] && !$conf['imageTextSplit'] && isset($conf['caption.'])) {
|
||||
$caption = $this->cObj->cObjGet($conf['caption.'], 'caption.');
|
||||
// Global caption, no splitting
|
||||
$caption = $this->cObj->stdWrap($caption, $conf['caption.']);
|
||||
}
|
||||
if ($conf['captionSplit'] && $conf['captionSplit.']['cObject']) {
|
||||
$legacyCaptionSplit = 1;
|
||||
$capSplit = isset($conf['captionSplit.']['token.']) ? $this->cObj->stdWrap($conf['captionSplit.']['token'], $conf['captionSplit.']['token.']) : $conf['captionSplit.']['token'];
|
||||
if (!$capSplit) {
|
||||
$capSplit = LF;
|
||||
}
|
||||
$captionArray = explode($capSplit, $this->cObj->cObjGetSingle($conf['captionSplit.']['cObject'], $conf['captionSplit.']['cObject.'], 'captionSplit.cObject'));
|
||||
foreach ($captionArray as $ca_key => $ca_val) {
|
||||
$captionArray[$ca_key] = isset($conf['captionSplit.']['stdWrap.']) ? $this->cObj->stdWrap(trim($captionArray[$ca_key]), $conf['captionSplit.']['stdWrap.']) : trim($captionArray[$ca_key]);
|
||||
}
|
||||
}
|
||||
$tablecode = '';
|
||||
$position = isset($conf['textPos.']) ? $this->cObj->stdWrap($conf['textPos'], $conf['textPos.']) : $conf['textPos'];
|
||||
$tmppos = $position & 7;
|
||||
$contentPosition = $position & 24;
|
||||
$align = $this->cObj->align[$tmppos];
|
||||
$cap = $caption ? 1 : 0;
|
||||
$txtMarg = isset($conf['textMargin.']) ? (int)$this->cObj->stdWrap($conf['textMargin'], $conf['textMargin.']) : (int)$conf['textMargin'];
|
||||
if (!$conf['textMargin_outOfText'] && $contentPosition < 16) {
|
||||
$txtMarg = 0;
|
||||
}
|
||||
$cols = isset($conf['cols.']) ? (int)$this->cObj->stdWrap($conf['cols'], $conf['cols.']) : (int)$conf['cols'];
|
||||
$rows = isset($conf['rows.']) ? (int)$this->cObj->stdWrap($conf['rows'], $conf['rows.']) : (int)$conf['rows'];
|
||||
$colspacing = isset($conf['colSpace.']) ? (int)$this->cObj->stdWrap($conf['colSpace'], $conf['colSpace.']) : (int)$conf['colSpace'];
|
||||
$rowspacing = isset($conf['rowSpace.']) ? (int)$this->cObj->stdWrap($conf['rowSpace'], $conf['rowSpace.']) : (int)$conf['rowSpace'];
|
||||
$border = isset($conf['border.']) ? (int)$this->cObj->stdWrap($conf['border'], $conf['border.']) : (int)$conf['border'];
|
||||
$border = $border ? 1 : 0;
|
||||
if ($border) {
|
||||
$borderColor = isset($conf['borderCol.']) ? $this->cObj->stdWrap($conf['borderCol'], $conf['borderCol.']) : $conf['borderCol'];
|
||||
if (!$borderColor) {
|
||||
$borderColor = 'black';
|
||||
}
|
||||
$borderThickness = isset($conf['borderThick.']) ? (int)$this->cObj->stdWrap($conf['borderThick'], $conf['borderThick.']) : (int)$conf['borderThick'];
|
||||
if (!$borderThickness) {
|
||||
$borderThickness = 'black';
|
||||
}
|
||||
}
|
||||
$caption_align = isset($conf['captionAlign.']) ? $this->cObj->stdWrap($conf['captionAlign'], $conf['captionAlign.']) : $conf['captionAlign'];
|
||||
if (!$caption_align) {
|
||||
$caption_align = $align;
|
||||
}
|
||||
// Generate cols
|
||||
$colCount = $cols > 1 ? $cols : 1;
|
||||
if ($colCount > $imgCount) {
|
||||
$colCount = $imgCount;
|
||||
}
|
||||
$rowCount = $colCount > 1 ? ceil($imgCount / $colCount) : $imgCount;
|
||||
// Generate rows
|
||||
if ($rows > 1) {
|
||||
$rowCount = $rows;
|
||||
if ($rowCount > $imgCount) {
|
||||
$rowCount = $imgCount;
|
||||
}
|
||||
$colCount = $rowCount > 1 ? ceil($imgCount / $rowCount) : $imgCount;
|
||||
}
|
||||
// Max Width
|
||||
$colRelations = isset($conf['colRelations.']) ? trim($this->cObj->stdWrap($conf['colRelations'], $conf['colRelations.'])) : trim($conf['colRelations']);
|
||||
$maxW = isset($conf['maxW.']) ? (int)$this->cObj->stdWrap($conf['maxW'], $conf['maxW.']) : (int)$conf['maxW'];
|
||||
$maxWInText = isset($conf['maxWInText.']) ? (int)$this->cObj->stdWrap($conf['maxWInText'], $conf['maxWInText.']) : (int)$conf['maxWInText'];
|
||||
// If maxWInText is not set, it's calculated to the 50 % of the max...
|
||||
if (!$maxWInText) {
|
||||
$maxWInText = round($maxW / 2);
|
||||
}
|
||||
// inText
|
||||
if ($maxWInText && $contentPosition >= 16) {
|
||||
$maxW = $maxWInText;
|
||||
}
|
||||
// If there is a max width and if colCount is greater than column
|
||||
if ($maxW && $colCount > 0) {
|
||||
$maxW = ceil(($maxW - $colspacing * ($colCount - 1) - $colCount * $border * $borderThickness * 2) / $colCount);
|
||||
}
|
||||
// Create the relation between rows
|
||||
$colMaxW = array();
|
||||
if ($colRelations) {
|
||||
$rel_parts = explode(':', $colRelations);
|
||||
$rel_total = 0;
|
||||
for ($a = 0; $a < $colCount; $a++) {
|
||||
$rel_parts[$a] = (int)$rel_parts[$a];
|
||||
$rel_total += $rel_parts[$a];
|
||||
}
|
||||
if ($rel_total) {
|
||||
for ($a = 0; $a < $colCount; $a++) {
|
||||
$colMaxW[$a] = round($maxW * $colCount / $rel_total * $rel_parts[$a]);
|
||||
}
|
||||
// The difference in size between the largest and smalles must be within a factor of ten.
|
||||
if (min($colMaxW) <= 0 || max($rel_parts) / min($rel_parts) > 10) {
|
||||
$colMaxW = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
$image_compression = isset($conf['image_compression.']) ? (int)$this->cObj->stdWrap($conf['image_compression'], $conf['image_compression.']) : (int)$conf['image_compression'];
|
||||
$image_effects = isset($conf['image_effects.']) ? (int)$this->cObj->stdWrap($conf['image_effects'], $conf['image_effects.']) : (int)$conf['image_effects'];
|
||||
$image_frames = isset($conf['image_frames.']['key.']) ? (int)$this->cObj->stdWrap($conf['image_frames.']['key'], $conf['image_frames.']['key.']) : (int)$conf['image_frames.']['key'];
|
||||
// Fetches pictures
|
||||
$splitArr = array();
|
||||
$splitArr['imgObjNum'] = $conf['imgObjNum'];
|
||||
$splitArr = $GLOBALS['TSFE']->tmpl->splitConfArray($splitArr, $imgCount);
|
||||
// EqualHeight
|
||||
$equalHeight = isset($conf['equalH.']) ? (int)$this->cObj->stdWrap($conf['equalH'], $conf['equalH.']) : (int)$conf['equalH'];
|
||||
// Initiate gifbuilder object in order to get dimensions AND calculate the imageWidth's
|
||||
if ($equalHeight) {
|
||||
$gifCreator = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Imaging\GifBuilder::class);
|
||||
$gifCreator->init();
|
||||
$relations = array();
|
||||
$relations_cols = array();
|
||||
$totalMaxW = $maxW * $colCount;
|
||||
for ($a = 0; $a < $imgCount; $a++) {
|
||||
$imgKey = $a + $imgStart;
|
||||
$imgInfo = $gifCreator->getImageDimensions($imgPath . $imgs[$imgKey]);
|
||||
// relationship between the original height and the wished height
|
||||
$relations[$a] = $imgInfo[1] / $equalHeight;
|
||||
// if relations is zero, then the addition of this value is omitted as
|
||||
// the image is not expected to display because of some error.
|
||||
if ($relations[$a]) {
|
||||
// Counts the total width of the row with the new height taken into consideration.
|
||||
$relations_cols[floor($a / $colCount)] += $imgInfo[0] / $relations[$a];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Contains the width of every image row
|
||||
$imageRowsFinalWidths = array();
|
||||
$imageRowsMaxHeights = array();
|
||||
$imgsTag = array();
|
||||
$origImages = array();
|
||||
for ($a = 0; $a < $imgCount; $a++) {
|
||||
$GLOBALS['TSFE']->register['IMAGE_NUM'] = $a;
|
||||
$GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $a;
|
||||
$imgKey = $a + $imgStart;
|
||||
if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($imgs[$imgKey])) {
|
||||
$this->setCurrentFileInContentObjectRenderer(intval($imgs[$imgKey]));
|
||||
}
|
||||
$totalImagePath = $imgPath . $imgs[$imgKey];
|
||||
$this->cObj->data[$this->cObj->currentValKey] = $totalImagePath;
|
||||
$imgObjNum = (int)$splitArr[$a]['imgObjNum'];
|
||||
$imgConf = $conf[$imgObjNum . '.'];
|
||||
if ($equalHeight) {
|
||||
$scale = 1;
|
||||
if ($totalMaxW) {
|
||||
$rowTotalMaxW = $relations_cols[floor($a / $colCount)];
|
||||
if ($rowTotalMaxW > $totalMaxW) {
|
||||
$scale = $rowTotalMaxW / $totalMaxW;
|
||||
}
|
||||
}
|
||||
// Transfer info to the imageObject. Please note, that
|
||||
$imgConf['file.']['height'] = round($equalHeight / $scale);
|
||||
unset($imgConf['file.']['width'], $imgConf['file.']['maxW'], $imgConf['file.']['maxH'], $imgConf['file.']['minW'], $imgConf['file.']['minH'], $imgConf['file.']['width.'], $imgConf['file.']['maxW.'], $imgConf['file.']['maxH.'], $imgConf['file.']['minW.'], $imgConf['file.']['minH.']);
|
||||
// Setting this to zero, so that it doesn't disturb
|
||||
$maxW = 0;
|
||||
}
|
||||
if ($maxW) {
|
||||
if (!empty($colMaxW)) {
|
||||
$imgConf['file.']['maxW'] = $colMaxW[$a % $colCount];
|
||||
} else {
|
||||
$imgConf['file.']['maxW'] = $maxW;
|
||||
}
|
||||
}
|
||||
// Image Object supplied:
|
||||
if (is_array($imgConf)) {
|
||||
if ($this->cObj->image_effects[$image_effects]) {
|
||||
$imgConf['file.']['params'] .= ' ' . $this->cObj->image_effects[$image_effects];
|
||||
}
|
||||
if ($image_frames) {
|
||||
if (is_array($conf['image_frames.'][$image_frames . '.'])) {
|
||||
$imgConf['file.']['m.'] = $conf['image_frames.'][$image_frames . '.'];
|
||||
}
|
||||
}
|
||||
if ($image_compression && $imgConf['file'] != 'GIFBUILDER') {
|
||||
if ($image_compression == 1) {
|
||||
$tempImport = $imgConf['file.']['import'];
|
||||
$tempImport_dot = $imgConf['file.']['import.'];
|
||||
unset($imgConf['file.']);
|
||||
$imgConf['file.']['import'] = $tempImport;
|
||||
$imgConf['file.']['import.'] = $tempImport_dot;
|
||||
} elseif (isset($this->cObj->image_compression[$image_compression])) {
|
||||
$imgConf['file.']['params'] .= ' ' . $this->cObj->image_compression[$image_compression]['params'];
|
||||
$imgConf['file.']['ext'] = $this->cObj->image_compression[$image_compression]['ext'];
|
||||
unset($imgConf['file.']['ext.']);
|
||||
}
|
||||
}
|
||||
// "alt", "title" and "longdesc" attributes:
|
||||
if ($imgConf['altText'] === '' && !is_array($imgConf['altText.'])) {
|
||||
$imgConf['altText'] = $conf['altText'];
|
||||
$imgConf['altText.'] = $conf['altText.'];
|
||||
}
|
||||
if ($imgConf['titleText'] === '' && !is_array($imgConf['titleText.'])) {
|
||||
$imgConf['titleText'] = $conf['titleText'];
|
||||
$imgConf['titleText.'] = $conf['titleText.'];
|
||||
}
|
||||
if ($imgConf['longdescURL'] === '' && !is_array($imgConf['longdescURL.'])) {
|
||||
$imgConf['longdescURL'] = $conf['longdescURL'];
|
||||
$imgConf['longdescURL.'] = $conf['longdescURL.'];
|
||||
}
|
||||
} else {
|
||||
$imgConf = array(
|
||||
'altText' => $conf['altText'],
|
||||
'titleText' => $conf['titleText'],
|
||||
'longdescURL' => $conf['longdescURL'],
|
||||
'file' => $totalImagePath
|
||||
);
|
||||
}
|
||||
$imgsTag[$imgKey] = $this->cObj->cObjGetSingle('IMAGE', $imgConf);
|
||||
// Store the original filepath
|
||||
$origImages[$imgKey] = $GLOBALS['TSFE']->lastImageInfo;
|
||||
$imageRowsFinalWidths[floor($a / $colCount)] += $GLOBALS['TSFE']->lastImageInfo[0];
|
||||
if ($GLOBALS['TSFE']->lastImageInfo[1] > $imageRowsMaxHeights[floor($a / $colCount)]) {
|
||||
$imageRowsMaxHeights[floor($a / $colCount)] = $GLOBALS['TSFE']->lastImageInfo[1];
|
||||
}
|
||||
}
|
||||
// Calculating the tableWidth:
|
||||
// TableWidth problems: It creates problems if the pictures are NOT as wide as the tableWidth.
|
||||
$tableWidth = max($imageRowsFinalWidths) + $colspacing * ($colCount - 1) + $colCount * $border * $borderThickness * 2;
|
||||
// Make table for pictures
|
||||
$index = ($imgIndex = $imgStart);
|
||||
$noRows = isset($conf['noRows.']) ? $this->cObj->stdWrap($conf['noRows'], $conf['noRows.']) : $conf['noRows'];
|
||||
$noCols = isset($conf['noCols.']) ? $this->cObj->stdWrap($conf['noCols'], $conf['noCols.']) : $conf['noCols'];
|
||||
if ($noRows) {
|
||||
$noCols = 0;
|
||||
}
|
||||
// noRows overrides noCols. They cannot exist at the same time.
|
||||
if ($equalHeight) {
|
||||
$noCols = 1;
|
||||
$noRows = 0;
|
||||
}
|
||||
$rowCount_temp = 1;
|
||||
$colCount_temp = $colCount;
|
||||
if ($noRows) {
|
||||
$rowCount_temp = $rowCount;
|
||||
$rowCount = 1;
|
||||
}
|
||||
if ($noCols) {
|
||||
$colCount = 1;
|
||||
}
|
||||
// col- and rowspans calculated
|
||||
$colspan = $colspacing ? $colCount * 2 - 1 : $colCount;
|
||||
$rowspan = ($rowspacing ? $rowCount * 2 - 1 : $rowCount) + $cap;
|
||||
// Edit icons:
|
||||
if (!is_array($conf['editIcons.'])) {
|
||||
$conf['editIcons.'] = array();
|
||||
}
|
||||
$editIconsHTML = $conf['editIcons'] && $GLOBALS['TSFE']->beUserLogin ? $this->cObj->editIcons('', $conf['editIcons'], $conf['editIcons.']) : '';
|
||||
// Strech out table:
|
||||
$tablecode = '';
|
||||
$flag = 0;
|
||||
$noStretchAndMarginCells = isset($conf['noStretchAndMarginCells.']) ? $this->cObj->stdWrap($conf['noStretchAndMarginCells'], $conf['noStretchAndMarginCells.']) : $conf['noStretchAndMarginCells'];
|
||||
if ($noStretchAndMarginCells != 1) {
|
||||
$tablecode .= '<tr>';
|
||||
if ($txtMarg && $align == 'right') {
|
||||
// If right aligned, the textborder is added on the right side
|
||||
$tablecode .= '<td rowspan="' . ($rowspan + 1) . '" valign="top"><span style="width: ' . $txtMarg . 'px; height: 1px;"></span>' . ($editIconsHTML ? '<br />' . $editIconsHTML : '') . '</td>';
|
||||
$editIconsHTML = '';
|
||||
$flag = 1;
|
||||
}
|
||||
$tablecode .= '<td colspan="' . $colspan . '"><span style="width: ' . $tableWidth . 'px; height: 1px;"></span></td>';
|
||||
if ($txtMarg && $align == 'left') {
|
||||
// If left aligned, the textborder is added on the left side
|
||||
$tablecode .= '<td rowspan="' . ($rowspan + 1) . '" valign="top"><span style="width: ' . $txtMarg . 'px; height: 1px;"></span>' . ($editIconsHTML ? '<br />' . $editIconsHTML : '') . '</td>';
|
||||
$editIconsHTML = '';
|
||||
$flag = 1;
|
||||
}
|
||||
if ($flag) {
|
||||
$tableWidth += $txtMarg + 1;
|
||||
}
|
||||
$tablecode .= '</tr>';
|
||||
}
|
||||
// draw table
|
||||
// Looping through rows. If 'noRows' is set, this is '1 time', but $rowCount_temp will hold the actual number of rows!
|
||||
for ($c = 0; $c < $rowCount; $c++) {
|
||||
// If this is NOT the first time in the loop AND if space is required, a row-spacer is added. In case of "noRows" rowspacing is done further down.
|
||||
if ($c && $rowspacing) {
|
||||
$tablecode .= '<tr><td colspan="' . $colspan . '"><span style="width: 1px; height: ' . $rowspacing . 'px;"></span></td></tr>';
|
||||
}
|
||||
// starting row
|
||||
$tablecode .= '<tr>';
|
||||
// Looping through the columns
|
||||
for ($b = 0; $b < $colCount_temp; $b++) {
|
||||
// If this is NOT the first iteration AND if column space is required. In case of "noCols", the space is done without a separate cell.
|
||||
if ($b && $colspacing) {
|
||||
if (!$noCols) {
|
||||
$tablecode .= '<td><span style="width: ' . $colspacing . 'px; height: 1px;"></span></td>';
|
||||
} else {
|
||||
$colSpacer = '<span style="width: ' . ($border ? $colspacing - 6 : $colspacing) . 'px; height: ' . ($imageRowsMaxHeights[$c] + ($border ? $borderThickness * 2 : 0)) . 'px;"></span>';
|
||||
$colSpacer = '<td valign="top">' . $colSpacer . '</td>';
|
||||
// added 160301, needed for the new "noCols"-table...
|
||||
$tablecode .= $colSpacer;
|
||||
}
|
||||
}
|
||||
if (!$noCols || $noCols && !$b) {
|
||||
// starting the cell. If "noCols" this cell will hold all images in the row, otherwise only a single image.
|
||||
$tablecode .= '<td valign="top">';
|
||||
if ($noCols) {
|
||||
$tablecode .= '<table width="' . $imageRowsFinalWidths[$c] . '" border="0" cellpadding="0" cellspacing="0"><tr>';
|
||||
}
|
||||
}
|
||||
// Looping through the rows IF "noRows" is set. "noRows" means that the rows of images is not rendered
|
||||
// by physical table rows but images are all in one column and spaced apart with clear-gifs. This loop is
|
||||
// only one time if "noRows" is not set.
|
||||
for ($a = 0; $a < $rowCount_temp; $a++) {
|
||||
// register previous imgIndex
|
||||
$GLOBALS['TSFE']->register['IMAGE_NUM'] = $imgIndex;
|
||||
$imgIndex = $index + $a * $colCount_temp;
|
||||
$GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imgIndex;
|
||||
if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($imgs[$imgIndex])) {
|
||||
$this->setCurrentFileInContentObjectRenderer(intval($imgs[$imgIndex]));
|
||||
}
|
||||
if ($imgsTag[$imgIndex]) {
|
||||
// Puts distance between the images IF "noRows" is set and this is the first iteration of the loop
|
||||
if ($rowspacing && $noRows && $a) {
|
||||
$tablecode .= '<span style="width: 1px; height: ' . $rowspacing . 'px;"></span><br />';
|
||||
}
|
||||
if ($legacyCaptionSplit) {
|
||||
$thisCaption = $captionArray[$imgIndex];
|
||||
} elseif (($conf['captionSplit'] || $conf['imageTextSplit']) && isset($conf['caption.'])) {
|
||||
$thisCaption = $this->cObj->cObjGet($conf['caption.'], 'caption.');
|
||||
$thisCaption = $this->cObj->stdWrap($thisCaption, $conf['caption.']);
|
||||
}
|
||||
$imageHTML = $imgsTag[$imgIndex] . '<br />';
|
||||
// this is necessary if the tablerows are supposed to space properly together! "noRows" is excluded because else the images "layer" together.
|
||||
$Talign = !trim($thisCaption) && !$noRows ? ' align="left"' : '';
|
||||
if ($border) {
|
||||
$imageHTML = '<table border="0" cellpadding="' . $borderThickness . '" cellspacing="0" bgcolor="' . $borderColor . '"' . $Talign . '><tr><td>' . $imageHTML . '</td></tr></table>';
|
||||
}
|
||||
$imageHTML .= $editIconsHTML;
|
||||
$editIconsHTML = '';
|
||||
// Adds caption.
|
||||
$imageHTML .= $thisCaption;
|
||||
if ($noCols) {
|
||||
$imageHTML = '<td valign="top">' . $imageHTML . '</td>';
|
||||
}
|
||||
// If noCols, put in table cell.
|
||||
$tablecode .= $imageHTML;
|
||||
}
|
||||
}
|
||||
$index++;
|
||||
if (!$noCols || $noCols && $b + 1 == $colCount_temp) {
|
||||
if ($noCols) {
|
||||
$tablecode .= '</tr></table>';
|
||||
}
|
||||
// In case of "noCols" we must finish the table that surrounds the images in the row.
|
||||
$tablecode .= '</td>';
|
||||
}
|
||||
}
|
||||
// ending row
|
||||
$tablecode .= '</tr>';
|
||||
}
|
||||
if ($c) {
|
||||
switch ($contentPosition) {
|
||||
case '0':
|
||||
|
||||
case '8':
|
||||
// below
|
||||
switch ($align) {
|
||||
case 'center':
|
||||
$table_align = 'margin-left: auto; margin-right: auto';
|
||||
break;
|
||||
case 'right':
|
||||
$table_align = 'margin-left: auto; margin-right: 0px';
|
||||
break;
|
||||
default:
|
||||
// Most of all: left
|
||||
$table_align = 'margin-left: 0px; margin-right: auto';
|
||||
}
|
||||
$table_align = 'style="' . $table_align . '"';
|
||||
break;
|
||||
case '16':
|
||||
// in text
|
||||
$table_align = 'align="' . $align . '"';
|
||||
break;
|
||||
default:
|
||||
$table_align = '';
|
||||
}
|
||||
// Table-tag is inserted
|
||||
$tablecode = '<table' . ($tableWidth ? ' width="' . $tableWidth . '"' : '') . ' border="0" cellspacing="0" cellpadding="0" ' . $table_align . ' class="imgtext-table">' . $tablecode;
|
||||
// If this value is not long since reset.
|
||||
if ($editIconsHTML) {
|
||||
$tablecode .= '<tr><td colspan="' . $colspan . '">' . $editIconsHTML . '</td></tr>';
|
||||
$editIconsHTML = '';
|
||||
}
|
||||
if ($cap) {
|
||||
$tablecode .= '<tr><td colspan="' . $colspan . '" align="' . $caption_align . '">' . $caption . '</td></tr>';
|
||||
}
|
||||
$tablecode .= '</table>';
|
||||
if (isset($conf['tableStdWrap.'])) {
|
||||
$tablecode = $this->cObj->stdWrap($tablecode, $conf['tableStdWrap.']);
|
||||
}
|
||||
}
|
||||
$spaceBelowAbove = isset($conf['spaceBelowAbove.']) ? (int)$this->cObj->stdWrap($conf['spaceBelowAbove'], $conf['spaceBelowAbove.']) : (int)$conf['spaceBelowAbove'];
|
||||
switch ($contentPosition) {
|
||||
case '0':
|
||||
// above
|
||||
$output = '<div style="text-align:' . $align . ';">' . $tablecode . '</div>' . $this->cObj->wrapSpace($content, ($spaceBelowAbove . '|0'));
|
||||
break;
|
||||
case '8':
|
||||
// below
|
||||
$output = $this->cObj->wrapSpace($content, ('0|' . $spaceBelowAbove)) . '<div style="text-align:' . $align . ';">' . $tablecode . '</div>';
|
||||
break;
|
||||
case '16':
|
||||
// in text
|
||||
$output = $tablecode . $content;
|
||||
break;
|
||||
case '24':
|
||||
// in text, no wrap
|
||||
$theResult = '';
|
||||
$theResult .= '<table border="0" cellspacing="0" cellpadding="0" class="imgtext-nowrap"><tr>';
|
||||
if ($align == 'right') {
|
||||
$theResult .= '<td valign="top">' . $content . '</td><td valign="top">' . $tablecode . '</td>';
|
||||
} else {
|
||||
$theResult .= '<td valign="top">' . $tablecode . '</td><td valign="top">' . $content . '</td>';
|
||||
}
|
||||
$theResult .= '</tr></table>';
|
||||
$output = $theResult;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$output = $content;
|
||||
}
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$output = $this->cObj->stdWrap($output, $conf['stdWrap.']);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the file reference object and sets it in the
|
||||
* currentFile property of the ContentObjectRenderer.
|
||||
*
|
||||
* This makes the file data available during image rendering.
|
||||
*
|
||||
* @param int $fileUid The UID of the file reference that should be loaded.
|
||||
* @return void
|
||||
*/
|
||||
protected function setCurrentFileInContentObjectRenderer($fileUid)
|
||||
{
|
||||
$imageFile = $this->getFileFactory()->getFileReferenceObject($fileUid);
|
||||
$this->cObj->setCurrentFile($imageFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file factory.
|
||||
*
|
||||
* @return ResourceFactory
|
||||
*/
|
||||
protected function getFileFactory()
|
||||
{
|
||||
if ($this->fileFactory === null) {
|
||||
$this->fileFactory = GeneralUtility::makeInstance(ResourceFactory::class);
|
||||
}
|
||||
|
||||
return $this->fileFactory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rendering of tables for offset
|
||||
*/
|
||||
class OffsetTableContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $tableParams = 'border="0" cellspacing="0" cellpadding="0"';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $default_tableParams = 'border="0" cellspacing="0" cellpadding="0"';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $tdParams = ' width="99%" valign="top"';
|
||||
|
||||
/**
|
||||
* Override default constructor to make it possible to instantiate this
|
||||
* class for rendering an offset table not in content object context
|
||||
*
|
||||
* @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj
|
||||
*/
|
||||
public function __construct(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj = null)
|
||||
{
|
||||
if (!is_null($cObj)) {
|
||||
$this->cObj = $cObj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendering the cObject, OTABLE
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
$tableParams = isset($conf['tableParams.']) ? $this->cObj->stdWrap($conf['tableParams'], $conf['tableParams.']) : $conf['tableParams'];
|
||||
if ($tableParams) {
|
||||
$this->tableParams = $tableParams;
|
||||
}
|
||||
$offset = isset($conf['offset.']) ? $this->cObj->stdWrap($conf['offset'], $conf['offset.']) : $conf['offset'];
|
||||
$content = $this->start($this->cObj->cObjGet($conf), $offset);
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapping the input content string in a table which will space it out from top/left/right/bottom
|
||||
*
|
||||
* @param string $content The HTML content string
|
||||
* @param string $offset List of offset parameters; x,y,r,b,w,h
|
||||
* @return string The HTML content string being wrapped in a <table> offsetting the content as the $offset parameters defined
|
||||
*/
|
||||
public function start($content, $offset)
|
||||
{
|
||||
$valPairs = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $offset . ',,,,,');
|
||||
if ($valPairs[0] || $valPairs[1] || $valPairs[2] || $valPairs[3] || $valPairs[4] || $valPairs[5]) {
|
||||
// If width is defined AND there has been no change to the default table params,
|
||||
// then extend them to a tablewidth of 1
|
||||
if ($valPairs[4] && $this->default_tableParams == $this->tableParams) {
|
||||
$this->tableParams .= ' width="1"';
|
||||
}
|
||||
// Init:
|
||||
$this->begin = LF . '<table ' . $this->tableParams . '>';
|
||||
$this->end = '</table>';
|
||||
$rows = array();
|
||||
$widthImg = '';
|
||||
$heightImg = '';
|
||||
// If width is required, set so bottom column will display for sure
|
||||
if ($valPairs[4]) {
|
||||
if (!$valPairs[3]) {
|
||||
$valPairs[3] = 1;
|
||||
}
|
||||
$widthImg = '<span style="width: ' . $valPairs[4] . 'px; height: 1px;"></span>';
|
||||
}
|
||||
// If height is required, set so right column will display for sure
|
||||
if ($valPairs[5]) {
|
||||
if (!$valPairs[2]) {
|
||||
$valPairs[2] = 1;
|
||||
}
|
||||
$valPairs[2] = 1;
|
||||
$heightImg = '<span style="width: 1px; height: ' . $valPairs[5] . 'px;"></span>';
|
||||
}
|
||||
// First row:
|
||||
// top
|
||||
if ($valPairs[1]) {
|
||||
$rows[1] .= '<tr>';
|
||||
$rows[1] .= '<td><span style="width: ' . ($valPairs[0] ?: 1) . 'px; height: ' . $valPairs[1] . 'px;"></span></td>';
|
||||
if ($valPairs[0]) {
|
||||
$rows[1] .= '<td></td>';
|
||||
}
|
||||
if ($valPairs[2]) {
|
||||
$rows[1] .= '<td></td>';
|
||||
}
|
||||
$rows[1] .= '</tr>';
|
||||
}
|
||||
// Middle row:
|
||||
$rows[2] .= '<tr>';
|
||||
if ($valPairs[0]) {
|
||||
$rows[2] .= $valPairs[1] ? '<td></td>' : '<td><span style="width: ' . $valPairs[0] . 'px; height: 1px;"></span></td>';
|
||||
}
|
||||
$rows[2] .= '<td' . $this->tdParams . '>' . $content . '</td>';
|
||||
if ($valPairs[2]) {
|
||||
$rows[2] .= $valPairs[3] ? '<td>' . $heightImg . '</td>' : '<td><span style="width: ' . $valPairs[2] . 'px; height: ' . ($valPairs[5] ?: 1) . 'px;"></span></td>';
|
||||
}
|
||||
$rows[2] .= '</tr>';
|
||||
// Bottom row:
|
||||
if ($valPairs[3]) {
|
||||
$rows[3] .= '<tr>';
|
||||
if ($valPairs[0]) {
|
||||
$rows[3] .= '<td></td>';
|
||||
}
|
||||
if ($valPairs[2]) {
|
||||
$rows[3] .= '<td>' . $widthImg . '</td>';
|
||||
}
|
||||
$rows[3] .= '<td><span style="width: ' . ($valPairs[2] ?: ($valPairs[4] ?: 1)) . 'px; height: ' . $valPairs[3] . 'px;"></span></td>';
|
||||
$rows[3] .= '</tr>';
|
||||
}
|
||||
return $this->begin . implode('', $rows) . $this->end;
|
||||
} else {
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,661 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Search class used for the content object SEARCHRESULT
|
||||
* and searching in database tables, typ. "pages" and "tt_content"
|
||||
* Used to generate search queries for TypoScript.
|
||||
* The class is included from "TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer"
|
||||
* based on whether there has been detected content in the GPvar "sword"
|
||||
*/
|
||||
class SearchResultContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $tables = array();
|
||||
|
||||
/**
|
||||
* Alternatively 'PRIMARY_KEY'; sorting by primary key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $group_by = 'PRIMARY_KEY';
|
||||
|
||||
/**
|
||||
* Standard SQL-operator between words
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $default_operator = 'AND';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $operator_translate_table_caseinsensitive = true;
|
||||
|
||||
/**
|
||||
* case-sensitive. Defines the words, which will be operators between words
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $operator_translate_table = array(
|
||||
array('+', 'AND'),
|
||||
array('|', 'AND'),
|
||||
array('-', 'AND NOT'),
|
||||
// english
|
||||
array('and', 'AND'),
|
||||
array('or', 'OR'),
|
||||
array('not', 'AND NOT')
|
||||
);
|
||||
|
||||
/**
|
||||
* Contains the search-words and operators
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $sword_array;
|
||||
|
||||
/**
|
||||
* Contains the query parts after processing.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $queryParts;
|
||||
|
||||
/**
|
||||
* This is set with the foreign table that 'pages' are connected to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $fTable;
|
||||
|
||||
/**
|
||||
* How many rows to offset from the beginning
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $res_offset = 0;
|
||||
|
||||
/**
|
||||
* How many results to show (0 = no limit)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $res_shows = 20;
|
||||
|
||||
/**
|
||||
* Intern: How many results, there was last time (with the exact same searchstring.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $res_count;
|
||||
|
||||
/**
|
||||
* List of pageIds.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $pageIdList = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $listOfSearchFields = '';
|
||||
|
||||
/**
|
||||
* Override default constructor to make it possible to instantiate this
|
||||
* class for indexed_search
|
||||
*
|
||||
* @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj
|
||||
*/
|
||||
public function __construct(ContentObjectRenderer $cObj = null)
|
||||
{
|
||||
if (!is_null($cObj)) {
|
||||
$this->cObj = $cObj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendering the cObject, SEARCHRESULT
|
||||
*
|
||||
* @param array $conf Array of TypoScript properties
|
||||
* @return string Output
|
||||
*/
|
||||
public function render($conf = array())
|
||||
{
|
||||
if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('sword') && \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scols')) {
|
||||
$this->register_and_explode_search_string(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('sword'));
|
||||
$this->register_tables_and_columns(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scols'), $conf['allowedCols']);
|
||||
// Depth
|
||||
$depth = 100;
|
||||
// The startId is found
|
||||
$theStartId = 0;
|
||||
if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype'))) {
|
||||
$temp_theStartId = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype');
|
||||
$rootLine = $GLOBALS['TSFE']->sys_page->getRootLine($temp_theStartId);
|
||||
// The page MUST have a rootline with the Level0-page of the current site inside!!
|
||||
foreach ($rootLine as $val) {
|
||||
if ($val['uid'] == $GLOBALS['TSFE']->tmpl->rootLine[0]['uid']) {
|
||||
$theStartId = $temp_theStartId;
|
||||
}
|
||||
}
|
||||
} elseif (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype')) {
|
||||
if (substr(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype'), 0, 1) == 'L') {
|
||||
$pointer = (int)substr(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype'), 1);
|
||||
$theRootLine = $GLOBALS['TSFE']->tmpl->rootLine;
|
||||
// location Data:
|
||||
$locDat_arr = explode(':', \TYPO3\CMS\Core\Utility\GeneralUtility::_POST('locationData'));
|
||||
$pId = (int)$locDat_arr[0];
|
||||
if ($pId) {
|
||||
$altRootLine = $GLOBALS['TSFE']->sys_page->getRootLine($pId);
|
||||
ksort($altRootLine);
|
||||
if (!empty($altRootLine)) {
|
||||
// Check if the rootline has the real Level0 in it!!
|
||||
$hitRoot = 0;
|
||||
$theNewRoot = array();
|
||||
foreach ($altRootLine as $val) {
|
||||
if ($hitRoot || $val['uid'] == $GLOBALS['TSFE']->tmpl->rootLine[0]['uid']) {
|
||||
$hitRoot = 1;
|
||||
$theNewRoot[] = $val;
|
||||
}
|
||||
}
|
||||
if ($hitRoot) {
|
||||
// Override the real rootline if any thing
|
||||
$theRootLine = $theNewRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
$key = $this->cObj->getKey($pointer, $theRootLine);
|
||||
$theStartId = $theRootLine[$key]['uid'];
|
||||
}
|
||||
}
|
||||
if (!$theStartId) {
|
||||
// If not set, we use current page
|
||||
$theStartId = $GLOBALS['TSFE']->id;
|
||||
}
|
||||
// Generate page-tree
|
||||
$this->pageIdList .= $this->cObj->getTreeList(-1 * $theStartId, $depth);
|
||||
$endClause = 'pages.uid IN (' . $this->pageIdList . ')
|
||||
AND pages.doktype in (' . $GLOBALS['TYPO3_CONF_VARS']['FE']['content_doktypes'] . ($conf['addExtUrlsAndShortCuts'] ? ',3,4' : '') . ')
|
||||
AND pages.no_search=0' . $this->cObj->enableFields($this->fTable) . $this->cObj->enableFields('pages');
|
||||
if ($conf['languageField.'][$this->fTable]) {
|
||||
// (using sys_language_uid which is the ACTUAL language of the page.
|
||||
// sys_language_content is only for selecting DISPLAY content!)
|
||||
$endClause .= ' AND ' . $this->fTable . '.' . $conf['languageField.'][$this->fTable] . ' = ' . (int)$GLOBALS['TSFE']->sys_language_uid;
|
||||
}
|
||||
// Build query
|
||||
$this->build_search_query($endClause);
|
||||
// Count...
|
||||
if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scount'))) {
|
||||
$this->res_count = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scount');
|
||||
} else {
|
||||
$this->count_query();
|
||||
}
|
||||
// Range
|
||||
$spointer = (int)\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('spointer');
|
||||
$range = isset($conf['range.']) ? $this->cObj->stdWrap($conf['range'], $conf['range.']) : $conf['range'];
|
||||
if ($range) {
|
||||
$theRange = (int)$range;
|
||||
} else {
|
||||
$theRange = 20;
|
||||
}
|
||||
// Order By:
|
||||
$noOrderBy = isset($conf['noOrderBy.']) ? $this->cObj->stdWrap($conf['noOrderBy'], $conf['noOrderBy.']) : $conf['noOrderBy'];
|
||||
if (!$noOrderBy) {
|
||||
$this->queryParts['ORDERBY'] = 'pages.lastUpdated, pages.tstamp';
|
||||
}
|
||||
$this->queryParts['LIMIT'] = $spointer . ',' . $theRange;
|
||||
// Search...
|
||||
$this->execute_query();
|
||||
if ($GLOBALS['TYPO3_DB']->sql_num_rows($this->result)) {
|
||||
$GLOBALS['TSFE']->register['SWORD_PARAMS'] = $this->get_searchwords();
|
||||
$total = $this->res_count;
|
||||
$rangeLow = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($spointer + 1, 1, $total);
|
||||
$rangeHigh = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($spointer + $theRange, 1, $total);
|
||||
// prev/next url:
|
||||
$target = isset($conf['target.']) ? $this->cObj->stdWrap($conf['target'], $conf['target.']) : $conf['target'];
|
||||
$LD = $GLOBALS['TSFE']->tmpl->linkData($GLOBALS['TSFE']->page, $target, 1, '', '', $this->cObj->getClosestMPvalueForPage($GLOBALS['TSFE']->page['uid']));
|
||||
$targetPart = $LD['target'] ? ' target="' . htmlspecialchars($LD['target']) . '"' : '';
|
||||
$urlParams = $this->cObj->URLqMark($LD['totalURL'], '&sword=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('sword')) . '&scols=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scols')) . '&stype=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype')) . '&scount=' . $total);
|
||||
// substitution:
|
||||
$result = str_replace(
|
||||
array(
|
||||
'###RANGELOW###',
|
||||
'###RANGEHIGH###',
|
||||
'###TOTAL###'
|
||||
),
|
||||
array(
|
||||
$rangeLow,
|
||||
$rangeHigh,
|
||||
$total
|
||||
),
|
||||
$this->cObj->cObjGetSingle($conf['layout'], $conf['layout.'], 'layout')
|
||||
);
|
||||
if ($rangeHigh < $total) {
|
||||
$next = $this->cObj->cObjGetSingle($conf['next'], $conf['next.'], 'next');
|
||||
$next = '<a href="' . htmlspecialchars(($urlParams . '&spointer=' . ($spointer + $theRange))) . '"' . $targetPart . $GLOBALS['TSFE']->ATagParams . '>' . $next . '</a>';
|
||||
} else {
|
||||
$next = '';
|
||||
}
|
||||
$result = str_replace('###NEXT###', $next, $result);
|
||||
if ($rangeLow > 1) {
|
||||
$prev = $this->cObj->cObjGetSingle($conf['prev'], $conf['prev.'], 'prev');
|
||||
$prev = '<a href="' . htmlspecialchars(($urlParams . '&spointer=' . ($spointer - $theRange))) . '"' . $targetPart . $GLOBALS['TSFE']->ATagParams . '>' . $prev . '</a>';
|
||||
} else {
|
||||
$prev = '';
|
||||
}
|
||||
$result = str_replace('###PREV###', $prev, $result);
|
||||
// Searching result
|
||||
$theValue = $this->cObj->cObjGetSingle($conf['resultObj'], $conf['resultObj.'], 'resultObj');
|
||||
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
|
||||
$cObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
|
||||
$cObj->setParent($this->cObj->data, $this->cObj->currentRecord);
|
||||
$renderCode = '';
|
||||
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($this->result)) {
|
||||
// versionOL() here? This is search result displays, is that possible to preview anyway?
|
||||
// Or are records selected here already future versions?
|
||||
$cObj->start($row);
|
||||
$renderCode .= $cObj->cObjGetSingle($conf['renderObj'], $conf['renderObj.'], 'renderObj');
|
||||
}
|
||||
$renderWrap = isset($conf['renderWrap.']) ? $this->cObj->stdWrap($conf['renderWrap'], $conf['renderWrap.']) : $conf['renderWrap'];
|
||||
$theValue .= $this->cObj->wrap($renderCode, $renderWrap);
|
||||
$theValue = str_replace('###RESULT###', $theValue, $result);
|
||||
} else {
|
||||
$theValue = $this->cObj->cObjGetSingle($conf['noResultObj'], $conf['noResultObj.'], 'noResultObj');
|
||||
}
|
||||
$GLOBALS['TT']->setTSlogMessage('Search in fields: ' . $this->listOfSearchFields);
|
||||
// Wrapping
|
||||
$content = $theValue;
|
||||
$wrap = isset($conf['wrap.']) ? $this->cObj->stdWrap($conf['wrap'], $conf['wrap.']) : $conf['wrap'];
|
||||
if ($wrap) {
|
||||
$content = $this->cObj->wrap($content, $wrap);
|
||||
}
|
||||
if (isset($conf['stdWrap.'])) {
|
||||
$content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
|
||||
}
|
||||
// Returning, do not cache the result of the search
|
||||
$GLOBALS['TSFE']->set_no_cache('Search result page');
|
||||
return $content;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the $this->tables-array.
|
||||
* The 'pages'-table is ALWAYS included as the search is page-based. Apart from this there may be one and only one table, joined with the pages-table. This table is the first table mentioned in the requested-list. If any more tables are set here, they are ignored.
|
||||
*
|
||||
* @param string $requestedCols is a list (-) of columns that we want to search. This could be input from the search-form (see TypoScript documentation)
|
||||
* @param string $allowedCols $allowedCols: is the list of columns, that MAY be searched. All allowed cols are set as result-fields. All requested cols MUST be in the allowed-fields list.
|
||||
* @return void
|
||||
*/
|
||||
public function register_tables_and_columns($requestedCols, $allowedCols)
|
||||
{
|
||||
$rCols = $this->explodeCols($requestedCols);
|
||||
$aCols = $this->explodeCols($allowedCols);
|
||||
foreach ($rCols as $k => $v) {
|
||||
$rCols[$k] = trim($v);
|
||||
if (in_array($rCols[$k], $aCols)) {
|
||||
$parts = explode('.', $rCols[$k]);
|
||||
$this->tables[$parts[0]]['searchfields'][] = $parts[1];
|
||||
}
|
||||
}
|
||||
$this->tables['pages']['primary_key'] = 'uid';
|
||||
$this->tables['pages']['resultfields'][] = 'uid';
|
||||
unset($this->tables['pages']['fkey']);
|
||||
foreach ($aCols as $k => $v) {
|
||||
$aCols[$k] = trim($v);
|
||||
$parts = explode('.', $aCols[$k]);
|
||||
$this->tables[$parts[0]]['resultfields'][] = $parts[1] . ' AS ' . str_replace('.', '_', $aCols[$k]);
|
||||
$this->tables[$parts[0]]['fkey'] = 'pid';
|
||||
}
|
||||
$this->fTable = '';
|
||||
foreach ($this->tables as $t => $v) {
|
||||
if ($t != 'pages') {
|
||||
if (!$this->fTable) {
|
||||
$this->fTable = $t;
|
||||
} else {
|
||||
unset($this->tables[$t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that can convert the syntax for entering which tables/fields the search should be conducted in.
|
||||
*
|
||||
* @param string $in This is the code-line defining the tables/fields to search. Syntax: '[table1].[field1]-[field2]-[field3] : [table2].[field1]-[field2]'
|
||||
* @return array An array where the values is "[table].[field]" strings to search
|
||||
* @see register_tables_and_columns()
|
||||
*/
|
||||
public function explodeCols($in)
|
||||
{
|
||||
$theArray = explode(':', $in);
|
||||
$out = array();
|
||||
foreach ($theArray as $val) {
|
||||
$val = trim($val);
|
||||
$parts = explode('.', $val);
|
||||
if ($parts[0] && $parts[1]) {
|
||||
$subparts = explode('-', $parts[1]);
|
||||
foreach ($subparts as $piece) {
|
||||
$piece = trim($piece);
|
||||
if ($piece) {
|
||||
$out[] = $parts[0] . '.' . $piece;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a search-string (WITHOUT SLASHES or else it'll be a little sppooky , NOW REMEMBER to unslash!!)
|
||||
* Sets up $this->sword_array op with operators.
|
||||
* This function uses $this->operator_translate_table as well as $this->default_operator
|
||||
*
|
||||
* @param string $sword The input search-word string.
|
||||
* @return void
|
||||
*/
|
||||
public function register_and_explode_search_string($sword)
|
||||
{
|
||||
$sword = trim($sword);
|
||||
if ($sword) {
|
||||
$components = $this->split($sword);
|
||||
// the searchword is stored here during the loop
|
||||
$s_sword = '';
|
||||
if (is_array($components)) {
|
||||
$i = 0;
|
||||
$lastoper = '';
|
||||
foreach ($components as $key => $val) {
|
||||
$operator = $this->get_operator($val);
|
||||
if ($operator) {
|
||||
$lastoper = $operator;
|
||||
} elseif (strlen($val) > 1) {
|
||||
// A searchword MUST be at least two characters long!
|
||||
$this->sword_array[$i]['sword'] = $val;
|
||||
$this->sword_array[$i]['oper'] = $lastoper ?: $this->default_operator;
|
||||
$lastoper = '';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to split a search-word line up into elements to search for. This function will detect boolean words like AND and OR, + and -, and even find sentences encapsulated in ""
|
||||
* This function could be re-written to be more clean and effective - yet it's not that important.
|
||||
*
|
||||
* @param string $origSword The raw sword string from outside
|
||||
* @param string $specchars Special chars which are used as operators (+- is default)
|
||||
* @param string $delchars Special chars which are deleted if the append the searchword (+-., is default)
|
||||
* @return mixed Returns an ARRAY if there were search words, otherwise the return value may be unset.
|
||||
*/
|
||||
public function split($origSword, $specchars = '+-', $delchars = '+.,-')
|
||||
{
|
||||
$sword = $origSword;
|
||||
$specs = '[' . preg_quote($specchars, '/') . ']';
|
||||
// As long as $sword is TRUE (that means $sword MUST be reduced little by little until its empty inside the loop!)
|
||||
while ($sword) {
|
||||
// There was a double-quote and we will then look for the ending quote.
|
||||
if (preg_match('/^"/', $sword)) {
|
||||
// Removes first double-quote
|
||||
$sword = preg_replace('/^"/', '', $sword);
|
||||
// Removes everything till next double-quote
|
||||
preg_match('/^[^"]*/', $sword, $reg);
|
||||
// reg[0] is the value, should not be trimmed
|
||||
$value[] = $reg[0];
|
||||
$sword = preg_replace('/^' . preg_quote($reg[0], '/') . '/', '', $sword);
|
||||
// Removes last double-quote
|
||||
$sword = trim(preg_replace('/^"/', '', $sword));
|
||||
} elseif (preg_match('/^' . $specs . '/', $sword, $reg)) {
|
||||
$value[] = $reg[0];
|
||||
// Removes = sign
|
||||
$sword = trim(preg_replace('/^' . $specs . '/', '', $sword));
|
||||
} elseif (preg_match('/[\\+\\-]/', $sword)) {
|
||||
// Check if $sword contains + or -
|
||||
// + and - shall only be interpreted as $specchars when there's whitespace before it
|
||||
// otherwise it's included in the searchword (e.g. "know-how")
|
||||
// explode $sword to single words
|
||||
$a_sword = explode(' ', $sword);
|
||||
// get first word
|
||||
$word = array_shift($a_sword);
|
||||
// Delete $delchars at end of string
|
||||
$word = rtrim($word, $delchars);
|
||||
// add searchword to values
|
||||
$value[] = $word;
|
||||
// re-build $sword
|
||||
$sword = implode(' ', $a_sword);
|
||||
} else {
|
||||
// There are no double-quotes around the value. Looking for next (space) or special char.
|
||||
preg_match('/^[^ ' . preg_quote($specchars, '/') . ']*/', $sword, $reg);
|
||||
// Delete $delchars at end of string
|
||||
$word = rtrim(trim($reg[0]), $delchars);
|
||||
$value[] = $word;
|
||||
$sword = trim(preg_replace('/^' . preg_quote($reg[0], '/') . '/', '', $sword));
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates the search-query.
|
||||
* In TypoScript this is used for searching only records not hidden, start/endtimed and fe_grouped! (enable-fields, see tt_content)
|
||||
* Sets $this->queryParts
|
||||
*
|
||||
* @param string $endClause Some extra conditions that the search must match.
|
||||
* @return bool Returns TRUE no matter what - sweet isn't it!
|
||||
* @access private
|
||||
* @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::SEARCHRESULT()
|
||||
*/
|
||||
public function build_search_query($endClause)
|
||||
{
|
||||
if (is_array($this->tables)) {
|
||||
$tables = $this->tables;
|
||||
$primary_table = '';
|
||||
// Primary key table is found.
|
||||
foreach ($tables as $key => $val) {
|
||||
if ($tables[$key]['primary_key']) {
|
||||
$primary_table = $key;
|
||||
}
|
||||
}
|
||||
if ($primary_table) {
|
||||
// Initialize query parts:
|
||||
$this->queryParts = array(
|
||||
'SELECT' => '',
|
||||
'FROM' => '',
|
||||
'WHERE' => '',
|
||||
'GROUPBY' => '',
|
||||
'ORDERBY' => '',
|
||||
'LIMIT' => ''
|
||||
);
|
||||
// Find tables / field names to select:
|
||||
$fieldArray = array();
|
||||
$tableArray = array();
|
||||
foreach ($tables as $key => $val) {
|
||||
$tableArray[] = $key;
|
||||
$resultfields = $tables[$key]['resultfields'];
|
||||
if (is_array($resultfields)) {
|
||||
foreach ($resultfields as $key2 => $val2) {
|
||||
$fieldArray[] = $key . '.' . $val2;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->queryParts['SELECT'] = implode(',', $fieldArray);
|
||||
$this->queryParts['FROM'] = implode(',', $tableArray);
|
||||
// Set join WHERE parts:
|
||||
$whereArray = array();
|
||||
$primary_table_and_key = $primary_table . '.' . $tables[$primary_table]['primary_key'];
|
||||
$primKeys = array();
|
||||
foreach ($tables as $key => $val) {
|
||||
$fkey = $tables[$key]['fkey'];
|
||||
if ($fkey) {
|
||||
$primKeys[] = $key . '.' . $fkey . '=' . $primary_table_and_key;
|
||||
}
|
||||
}
|
||||
if (!empty($primKeys)) {
|
||||
$whereArray[] = '(' . implode(' OR ', $primKeys) . ')';
|
||||
}
|
||||
// Additional where clause:
|
||||
if (trim($endClause)) {
|
||||
$whereArray[] = trim($endClause);
|
||||
}
|
||||
// Add search word where clause:
|
||||
$query_part = $this->build_search_query_for_searchwords();
|
||||
if (!$query_part) {
|
||||
$query_part = '(0!=0)';
|
||||
}
|
||||
$whereArray[] = '(' . $query_part . ')';
|
||||
// Implode where clauses:
|
||||
$this->queryParts['WHERE'] = implode(' AND ', $whereArray);
|
||||
// Group by settings:
|
||||
if ($this->group_by) {
|
||||
if ($this->group_by == 'PRIMARY_KEY') {
|
||||
$this->queryParts['GROUPBY'] = $primary_table_and_key;
|
||||
} else {
|
||||
$this->queryParts['GROUPBY'] = $this->group_by;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the part of the SQL-sentence, that searches for the search-words ($this->sword_array)
|
||||
*
|
||||
* @return string Part of where class limiting result to the those having the search word.
|
||||
* @access private
|
||||
*/
|
||||
public function build_search_query_for_searchwords()
|
||||
{
|
||||
if (is_array($this->sword_array)) {
|
||||
$main_query_part = array();
|
||||
foreach ($this->sword_array as $key => $val) {
|
||||
$s_sword = $this->sword_array[$key]['sword'];
|
||||
// Get subQueryPart
|
||||
$sub_query_part = array();
|
||||
$this->listOfSearchFields = '';
|
||||
foreach ($this->tables as $key3 => $val3) {
|
||||
$searchfields = $this->tables[$key3]['searchfields'];
|
||||
if (is_array($searchfields)) {
|
||||
foreach ($searchfields as $key2 => $val2) {
|
||||
$this->listOfSearchFields .= $key3 . '.' . $val2 . ',';
|
||||
$sub_query_part[] = $key3 . '.' . $val2 . ' LIKE \'%' . $GLOBALS['TYPO3_DB']->quoteStr($s_sword, $key3) . '%\'';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($sub_query_part)) {
|
||||
$main_query_part[] = $this->sword_array[$key]['oper'];
|
||||
$main_query_part[] = '(' . implode(' OR ', $sub_query_part) . ')';
|
||||
}
|
||||
}
|
||||
if (!empty($main_query_part)) {
|
||||
// Remove first part anyways.
|
||||
unset($main_query_part[0]);
|
||||
return implode(' ', $main_query_part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns an SQL search-operator (eg. AND, OR, NOT) translated from the current localized set of operators (eg. in danish OG, ELLER, IKKE).
|
||||
*
|
||||
* @param string $operator The possible operator to find in the internal operator array.
|
||||
* @return string If found, the SQL operator for the localized input operator.
|
||||
* @access private
|
||||
*/
|
||||
public function get_operator($operator)
|
||||
{
|
||||
$operator = trim($operator);
|
||||
$op_array = $this->operator_translate_table;
|
||||
if ($this->operator_translate_table_caseinsensitive) {
|
||||
// case-conversion is charset insensitive, but it doesn't spoil
|
||||
// anything if input string AND operator table is already converted
|
||||
$operator = strtolower($operator);
|
||||
}
|
||||
foreach ($op_array as $key => $val) {
|
||||
$item = $op_array[$key][0];
|
||||
if ($this->operator_translate_table_caseinsensitive) {
|
||||
// See note above.
|
||||
$item = strtolower($item);
|
||||
}
|
||||
if ($operator == $item) {
|
||||
return $op_array[$key][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the results and sets the result in $this->res_count
|
||||
*
|
||||
* @return bool TRUE, if $this->query was found
|
||||
*/
|
||||
public function count_query()
|
||||
{
|
||||
if (is_array($this->queryParts)) {
|
||||
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($this->queryParts['SELECT'], $this->queryParts['FROM'], $this->queryParts['WHERE'], $this->queryParts['GROUPBY']);
|
||||
$this->res_count = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the search, sets result pointer in $this->result
|
||||
*
|
||||
* @return bool TRUE, if $this->query was set and query performed
|
||||
*/
|
||||
public function execute_query()
|
||||
{
|
||||
if (is_array($this->queryParts)) {
|
||||
$this->result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($this->queryParts);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns URL-parameters with the current search words.
|
||||
* Used when linking to result pages so that search words can be highlighted.
|
||||
*
|
||||
* @return string URL-parameters with the searchwords
|
||||
*/
|
||||
public function get_searchwords()
|
||||
{
|
||||
$SWORD_PARAMS = '';
|
||||
if (is_array($this->sword_array)) {
|
||||
foreach ($this->sword_array as $key => $val) {
|
||||
$SWORD_PARAMS .= '&sword_list[]=' . rawurlencode($val['sword']);
|
||||
}
|
||||
}
|
||||
return $SWORD_PARAMS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with the search words in
|
||||
*
|
||||
* @return array IF the internal sword_array contained search words it will return these, otherwise "void
|
||||
*/
|
||||
public function get_searchwordsArray()
|
||||
{
|
||||
if (is_array($this->sword_array)) {
|
||||
foreach ($this->sword_array as $key => $val) {
|
||||
$swords[] = $val['sword'];
|
||||
}
|
||||
}
|
||||
return $swords;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\ContentObject;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Rendering of tables for content positioning
|
||||
*
|
||||
* @see ContentObjectRenderer::CTABLE()
|
||||
*/
|
||||
class TableRenderer
|
||||
{
|
||||
/**
|
||||
* offset, x
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $offX = 0;
|
||||
|
||||
/**
|
||||
* offset, y
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $offY = 0;
|
||||
|
||||
/**
|
||||
* top menu
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $tm = '';
|
||||
|
||||
/**
|
||||
* left menu
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $lm = '';
|
||||
|
||||
/**
|
||||
* right menu
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $rm = '';
|
||||
|
||||
/**
|
||||
* bottom menu
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $bm = '';
|
||||
|
||||
/**
|
||||
* content
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* top menu TDparams
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $tmTDparams = 'valign="top"';
|
||||
|
||||
/**
|
||||
* left menu TDparams
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $lmTDparams = 'valign="top"';
|
||||
|
||||
/**
|
||||
* right menu TDparams
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $rmTDparams = 'valign="top"';
|
||||
|
||||
/**
|
||||
* bottom menu TDparams
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $bmTDparams = 'valign="top"';
|
||||
|
||||
/**
|
||||
* content TDparams
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $contentTDparams = 'valign="top"';
|
||||
|
||||
/**
|
||||
* content margin, left
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $cMl = 1;
|
||||
|
||||
/**
|
||||
* content margin, right
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $cMr = 1;
|
||||
|
||||
/**
|
||||
* content margin, top
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $cMt = 0;
|
||||
|
||||
/**
|
||||
* content margin, bottom
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $cMb = 1;
|
||||
|
||||
/**
|
||||
* Places a little gif-spacer in the bottom of the content frame
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $contentW = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $tableParams = 'border="0" cellspacing="0" cellpadding="0"';
|
||||
|
||||
/**
|
||||
* Wrapping internal vars ->tm, ->lm, ->rm, ->bm and ->content in a table where each content part is stored in a cell.
|
||||
* The two arguments to this function defines some offsets and margins to use in the arrangement of the content in the table.
|
||||
*
|
||||
* @param string $offset List of offset parameters; x,y
|
||||
* @param string $cMargins List of margin parameters; left, top, right, bottom
|
||||
* @return string The content strings wrapped in a <table> as the parameters defined
|
||||
* @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::CTABLE()
|
||||
*/
|
||||
public function start($offset, $cMargins)
|
||||
{
|
||||
$offArr = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $offset);
|
||||
$cMargArr = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $cMargins);
|
||||
$cols = 0;
|
||||
$rows = 0;
|
||||
if ($this->lm) {
|
||||
$cols++;
|
||||
}
|
||||
if ($this->rm) {
|
||||
$cols++;
|
||||
}
|
||||
if ($cMargArr[0]) {
|
||||
$cols++;
|
||||
}
|
||||
if ($cMargArr[2]) {
|
||||
$cols++;
|
||||
}
|
||||
if ($cMargArr[1] || $cMargArr[3] || $this->tm || $this->bm || $this->content || $this->contentW) {
|
||||
$cols++;
|
||||
}
|
||||
if ($cMargArr[1]) {
|
||||
$rows++;
|
||||
}
|
||||
if ($cMargArr[3]) {
|
||||
$rows++;
|
||||
}
|
||||
if ($this->tm) {
|
||||
$rows++;
|
||||
}
|
||||
if ($this->bm) {
|
||||
$rows++;
|
||||
}
|
||||
if ($this->content) {
|
||||
$rows++;
|
||||
}
|
||||
if ($this->contentW) {
|
||||
$rows++;
|
||||
}
|
||||
if (!$rows && $cols) {
|
||||
// If there are no rows in the middle but still som columns...
|
||||
$rows = 1;
|
||||
}
|
||||
if ($rows && $cols) {
|
||||
$res = LF . '<table ' . $this->tableParams . '>';
|
||||
// Top offset:
|
||||
if ($offArr[1]) {
|
||||
$xoff = $offArr[0] ? 1 : 0;
|
||||
if ($cols + $xoff > 1) {
|
||||
$colspan = ' colspan="' . ($cols + $xoff) . '"';
|
||||
}
|
||||
$res .= '<tr><td' . $colspan . '><span style="width: 1px; height: ' . $offArr[1] . 'px;"></span></td></tr>';
|
||||
}
|
||||
// The rows:
|
||||
if ($rows > 1) {
|
||||
$rowspan = ' rowspan="' . $rows . '"';
|
||||
}
|
||||
$res .= '<tr>';
|
||||
if ($offArr[0]) {
|
||||
$res .= '<td' . $rowspan . '><span style="width: ' . $offArr[0] . 'px; height: 1px;"></span></td>';
|
||||
}
|
||||
if ($this->lm) {
|
||||
$res .= '<td' . $rowspan . ' ' . $this->lmTDparams . '>' . $this->lm . '</td>';
|
||||
}
|
||||
if ($cMargArr[0]) {
|
||||
$res .= '<td' . $rowspan . '><span style="width: ' . $cMargArr[0] . 'px; height: 1px;"></span></td>';
|
||||
}
|
||||
// Content...
|
||||
$middle = array();
|
||||
if ($this->tm) {
|
||||
$middle[] = '<td ' . $this->tmTDparams . '>' . $this->tm . '</td>';
|
||||
}
|
||||
if ($cMargArr[1]) {
|
||||
$middle[] = '<td><span style="width: 1px; height: ' . $cMargArr[1] . 'px;"></span></td>';
|
||||
}
|
||||
if ($this->content) {
|
||||
$middle[] = '<td ' . $this->contentTDparams . '>' . $this->content . '</td>';
|
||||
}
|
||||
if ($cMargArr[3]) {
|
||||
$middle[] = '<td><span style="width: 1px; height: ' . $cMargArr[3] . 'px;"></span></td>';
|
||||
}
|
||||
if ($this->bm) {
|
||||
$middle[] = '<td ' . $this->bmTDparams . '>' . $this->bm . '</td>';
|
||||
}
|
||||
if ($this->contentW) {
|
||||
$middle[] = '<td><span style="width: ' . $this->contentW . 'px; height: 1px;"></span></td>';
|
||||
}
|
||||
if (isset($middle[0])) {
|
||||
$res .= $middle[0];
|
||||
}
|
||||
// Left of content
|
||||
if ($cMargArr[2]) {
|
||||
$res .= '<td' . $rowspan . '><span style="width: ' . $cMargArr[2] . 'px; height: 1px;"></span></td>';
|
||||
}
|
||||
if ($this->rm) {
|
||||
$res .= '<td' . $rowspan . ' ' . $this->rmTDparams . '>' . $this->rm . '</td>';
|
||||
}
|
||||
$res .= '</tr>';
|
||||
// More than the two rows
|
||||
$mCount = count($middle);
|
||||
for ($a = 1; $a < $mCount; $a++) {
|
||||
$res .= '<tr>' . $middle[$a] . '</tr>';
|
||||
}
|
||||
$res .= '</table>';
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Controller;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\MailUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
|
||||
/**
|
||||
* Formmail class
|
||||
* used to submit data, and hooks into TSFE
|
||||
*/
|
||||
class FormDataSubmissionController
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $reserved_names = 'recipient,recipient_copy,auto_respond_msg,auto_respond_checksum,redirect,subject,attachment,from_email,from_name,replyto_email,replyto_name,organisation,priority,html_enabled,quoted_printable,submit_x,submit_y';
|
||||
|
||||
/**
|
||||
* Collection of suspicious header data, used for logging
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dirtyHeaders = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $characterSet;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $subject;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fromName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $replyToName;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $organisation;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fromAddress;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $replyToAddress;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $priority;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $autoRespondMessage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $encoding = 'quoted-printable';
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Mail\MailMessage
|
||||
*/
|
||||
protected $mailMessage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $recipient;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $plainContent = '';
|
||||
|
||||
/**
|
||||
* @var array Files to clean up at the end (attachments)
|
||||
*/
|
||||
protected $temporaryFiles = array();
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
|
||||
*/
|
||||
protected $frontendController = null;
|
||||
|
||||
/**
|
||||
* hook to be executed by TypoScriptFrontendController
|
||||
*
|
||||
* @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $frontendController
|
||||
*/
|
||||
public function checkDataSubmission($frontendController)
|
||||
{
|
||||
$this->frontendController = $frontendController;
|
||||
|
||||
// Checks if any email-submissions
|
||||
$formtype_mail = isset($_POST['formtype_mail']) || isset($_POST['formtype_mail_x']);
|
||||
if ($formtype_mail) {
|
||||
$refInfo = parse_url(GeneralUtility::getIndpEnv('HTTP_REFERER'));
|
||||
if (GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY') == $refInfo['host'] || $this->frontendController->TYPO3_CONF_VARS['SYS']['doNotCheckReferer']) {
|
||||
if ($this->locDataCheck($_POST['locationData'])) {
|
||||
if ($formtype_mail) {
|
||||
$this->prepareAndSend();
|
||||
$GLOBALS['TT']->setTSlogMessage('"Check Data Submission": Return value: email', 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$GLOBALS['TT']->setTSlogMessage('"Check Data Submission": HTTP_HOST and REFERER HOST did not match when processing submitted formdata!', 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a formmail submission can be sent as email
|
||||
*
|
||||
* @param string $locationData The input from $_POST['locationData']
|
||||
* @return void|int
|
||||
*/
|
||||
protected function locDataCheck($locationData)
|
||||
{
|
||||
$locData = explode(':', $locationData);
|
||||
if (!$locData[1] || $this->frontendController->sys_page->checkRecord($locData[1], $locData[2], 1)) {
|
||||
// $locData[1] -check means that a record is checked only if the locationData has a value for a record else than the page.
|
||||
if (!empty($this->frontendController->sys_page->getPage($locData[0]))) {
|
||||
return 1;
|
||||
}
|
||||
$GLOBALS['TT']->setTSlogMessage('LocationData Error: The page pointed to by location data (' . $locationData . ') was not accessible.', 2);
|
||||
} else {
|
||||
$GLOBALS['TT']->setTSlogMessage('LocationData Error: Location data (' . $locationData . ') record pointed to was not accessible.', 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the emails from the formmail content object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareAndSend()
|
||||
{
|
||||
$EMAIL_VARS = GeneralUtility::_POST();
|
||||
$locationData = $EMAIL_VARS['locationData'];
|
||||
unset($EMAIL_VARS['locationData']);
|
||||
unset($EMAIL_VARS['formtype_mail'], $EMAIL_VARS['formtype_mail_x'], $EMAIL_VARS['formtype_mail_y']);
|
||||
$integrityCheck = $this->frontendController->TYPO3_CONF_VARS['FE']['strictFormmail'];
|
||||
if (!$this->frontendController->TYPO3_CONF_VARS['FE']['secureFormmail']) {
|
||||
// Check recipient field:
|
||||
// These two fields are the ones which contain recipient addresses that can be misused to send mail from foreign servers.
|
||||
$encodedFields = explode(',', 'recipient, recipient_copy');
|
||||
foreach ($encodedFields as $fieldKey) {
|
||||
if ((string)$EMAIL_VARS[$fieldKey] !== '') {
|
||||
// Decode...
|
||||
if ($res = \TYPO3\CMS\Compatibility6\Utility\FormUtility::codeString($EMAIL_VARS[$fieldKey], true)) {
|
||||
$EMAIL_VARS[$fieldKey] = $res;
|
||||
} elseif ($integrityCheck) {
|
||||
// Otherwise abort:
|
||||
$GLOBALS['TT']->setTSlogMessage('"Formmail" discovered a field (' . $fieldKey . ') which could not be decoded to a valid string. Sending formmail aborted due to security reasons!', 3);
|
||||
return;
|
||||
} else {
|
||||
$GLOBALS['TT']->setTSlogMessage('"Formmail" discovered a field (' . $fieldKey . ') which could not be decoded to a valid string. The security level accepts this, but you should consider a correct coding though!', 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$locData = explode(':', $locationData);
|
||||
$record = $this->frontendController->sys_page->checkRecord($locData[1], $locData[2], 1);
|
||||
$EMAIL_VARS['recipient'] = $record['subheader'];
|
||||
$EMAIL_VARS['recipient_copy'] = $this->extractRecipientCopy($record['bodytext']);
|
||||
}
|
||||
// Hook for preprocessing of the content for formmails:
|
||||
if (is_array($this->frontendController->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sendFormmail-PreProcClass'])) {
|
||||
foreach ($this->frontendController->TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['sendFormmail-PreProcClass'] as $_classRef) {
|
||||
$_procObj = GeneralUtility::getUserObj($_classRef);
|
||||
$EMAIL_VARS = $_procObj->sendFormmail_preProcessVariables($EMAIL_VARS, $this);
|
||||
}
|
||||
}
|
||||
$this->start($EMAIL_VARS);
|
||||
$r = $this->sendtheMail();
|
||||
$GLOBALS['TT']->setTSlogMessage('"Formmail" invoked, sending mail to ' . $EMAIL_VARS['recipient'], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the value of recipient copy field from a formmail CE bodytext
|
||||
*
|
||||
* @param string $bodytext The content of the related bodytext field
|
||||
* @return string The value of the recipient_copy field, or an empty string
|
||||
*/
|
||||
protected function extractRecipientCopy($bodytext)
|
||||
{
|
||||
$fdef = array();
|
||||
//|recipient_copy=hidden|karsten@localhost.localdomain
|
||||
preg_match('/^[\\s]*\\|[\\s]*recipient_copy[\\s]*=[\\s]*hidden[\\s]*\\|(.*)$/m', $bodytext, $fdef);
|
||||
return $fdef[1] ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Start function
|
||||
* This class is able to generate a mail in formmail-style from the data in $V
|
||||
* Fields:
|
||||
*
|
||||
* [recipient]: email-adress of the one to receive the mail. If array, then all values are expected to be recipients
|
||||
* [attachment]: ....
|
||||
*
|
||||
* [subject]: The subject of the mail
|
||||
* [from_email]: Sender email. If not set, [email] is used
|
||||
* [from_name]: Sender name. If not set, [name] is used
|
||||
* [replyto_email]: Reply-to email. If not set [from_email] is used
|
||||
* [replyto_name]: Reply-to name. If not set [from_name] is used
|
||||
* [organisation]: Organization (header)
|
||||
* [priority]: Priority, 1-5, default 3
|
||||
* [html_enabled]: If mail is sent as html
|
||||
* [use_base64]: If set, base64 encoding will be used instead of quoted-printable
|
||||
*
|
||||
* @param array $valueList Contains values for the field names listed above (with slashes removed if from POST input)
|
||||
* @param bool $base64 Whether to base64 encode the mail content
|
||||
* @return void
|
||||
*/
|
||||
public function start($valueList, $base64 = false)
|
||||
{
|
||||
$this->mailMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
|
||||
if ($GLOBALS['TSFE']->config['config']['formMailCharset']) {
|
||||
// Respect formMailCharset if it was set
|
||||
$this->characterSet = $GLOBALS['TSFE']->csConvObj->parse_charset($GLOBALS['TSFE']->config['config']['formMailCharset']);
|
||||
} elseif ($GLOBALS['TSFE']->metaCharset != $GLOBALS['TSFE']->renderCharset) {
|
||||
// Use metaCharset for mail if different from renderCharset
|
||||
$this->characterSet = $GLOBALS['TSFE']->metaCharset;
|
||||
} else {
|
||||
// Otherwise use renderCharset as default
|
||||
$this->characterSet = $GLOBALS['TSFE']->renderCharset;
|
||||
}
|
||||
if ($base64 || $valueList['use_base64']) {
|
||||
$this->encoding = 'base64';
|
||||
}
|
||||
if (isset($valueList['recipient'])) {
|
||||
// Convert form data from renderCharset to mail charset
|
||||
$this->subject = $valueList['subject'] ? $valueList['subject'] : 'Formmail on ' . GeneralUtility::getIndpEnv('HTTP_HOST');
|
||||
$this->subject = $this->sanitizeHeaderString($this->subject);
|
||||
$this->fromName = $valueList['from_name'] ? $valueList['from_name'] : ($valueList['name'] ? $valueList['name'] : '');
|
||||
$this->fromName = $this->sanitizeHeaderString($this->fromName);
|
||||
$this->replyToName = $valueList['replyto_name'] ? $valueList['replyto_name'] : $this->fromName;
|
||||
$this->replyToName = $this->sanitizeHeaderString($this->replyToName);
|
||||
$this->organisation = $valueList['organisation'] ? $valueList['organisation'] : '';
|
||||
$this->organisation = $this->sanitizeHeaderString($this->organisation);
|
||||
$this->fromAddress = $valueList['from_email'] ? $valueList['from_email'] : ($valueList['email'] ? $valueList['email'] : '');
|
||||
if (!GeneralUtility::validEmail($this->fromAddress)) {
|
||||
$this->fromAddress = MailUtility::getSystemFromAddress();
|
||||
$this->fromName = MailUtility::getSystemFromName();
|
||||
}
|
||||
$this->replyToAddress = $valueList['replyto_email'] ? $valueList['replyto_email'] : $this->fromAddress;
|
||||
$this->priority = $valueList['priority'] ? MathUtility::forceIntegerInRange($valueList['priority'], 1, 5) : 3;
|
||||
// Auto responder
|
||||
$this->autoRespondMessage = trim($valueList['auto_respond_msg']) && $this->fromAddress ? trim($valueList['auto_respond_msg']) : '';
|
||||
if ($this->autoRespondMessage !== '') {
|
||||
// Check if the value of the auto responder message has been modified with evil intentions
|
||||
$autoRespondChecksum = $valueList['auto_respond_checksum'];
|
||||
$correctHmacChecksum = GeneralUtility::hmac($this->autoRespondMessage, 'content_form');
|
||||
if ($autoRespondChecksum !== $correctHmacChecksum) {
|
||||
GeneralUtility::sysLog('Possible misuse of DataSubmissionController auto respond method. Subject: ' . $valueList['subject'], 'core', GeneralUtility::SYSLOG_SEVERITY_ERROR);
|
||||
return;
|
||||
} else {
|
||||
$this->autoRespondMessage = $this->sanitizeHeaderString($this->autoRespondMessage);
|
||||
}
|
||||
}
|
||||
$plainTextContent = '';
|
||||
$htmlContent = '<table border="0" cellpadding="2" cellspacing="2">';
|
||||
// Runs through $V and generates the mail
|
||||
if (is_array($valueList)) {
|
||||
foreach ($valueList as $key => $val) {
|
||||
if (!GeneralUtility::inList($this->reserved_names, $key)) {
|
||||
$space = strlen($val) > 60 ? LF : '';
|
||||
$val = is_array($val) ? implode($val, LF) : $val;
|
||||
// Convert form data from renderCharset to mail charset (HTML may use entities)
|
||||
$plainTextValue = $val;
|
||||
$HtmlValue = htmlspecialchars($val);
|
||||
$plainTextContent .= strtoupper($key) . ': ' . $space . $plainTextValue . LF . $space;
|
||||
$htmlContent .= '<tr><td bgcolor="#eeeeee"><font face="Verdana" size="1"><strong>' . strtoupper($key) . '</strong></font></td><td bgcolor="#eeeeee"><font face="Verdana" size="1">' . nl2br($HtmlValue) . ' </font></td></tr>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$htmlContent .= '</table>';
|
||||
$this->plainContent = $plainTextContent;
|
||||
if ($valueList['html_enabled']) {
|
||||
$this->mailMessage->setBody($htmlContent, 'text/html', $this->characterSet);
|
||||
$this->mailMessage->addPart($plainTextContent, 'text/plain', $this->characterSet);
|
||||
} else {
|
||||
$this->mailMessage->setBody($plainTextContent, 'text/plain', $this->characterSet);
|
||||
}
|
||||
for ($a = 0; $a < 10; $a++) {
|
||||
$variableName = 'attachment' . ($a ?: '');
|
||||
if (!isset($_FILES[$variableName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($_FILES[$variableName]['error'] !== UPLOAD_ERR_OK) {
|
||||
GeneralUtility::sysLog(
|
||||
'Error in uploaded file in DataSubmissionController: temporary file "' .
|
||||
$_FILES[$variableName]['tmp_name'] . '" ("' . $_FILES[$variableName]['name'] . '") Error code: ' .
|
||||
$_FILES[$variableName]['error'],
|
||||
'core',
|
||||
GeneralUtility::SYSLOG_SEVERITY_ERROR
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_uploaded_file($_FILES[$variableName]['tmp_name'])) {
|
||||
GeneralUtility::sysLog(
|
||||
'Possible abuse of DataSubmissionController: temporary file "' . $_FILES[$variableName]['tmp_name'] .
|
||||
'" ("' . $_FILES[$variableName]['name'] . '") was not an uploaded file.',
|
||||
'core',
|
||||
GeneralUtility::SYSLOG_SEVERITY_ERROR
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$theFile = GeneralUtility::upload_to_tempfile($_FILES[$variableName]['tmp_name']);
|
||||
$theName = $_FILES[$variableName]['name'];
|
||||
if ($theFile && file_exists($theFile)) {
|
||||
if (filesize($theFile) < $GLOBALS['TYPO3_CONF_VARS']['FE']['formmailMaxAttachmentSize']) {
|
||||
$this->mailMessage->attach(\Swift_Attachment::fromPath($theFile)->setFilename($theName));
|
||||
}
|
||||
}
|
||||
$this->temporaryFiles[] = $theFile;
|
||||
}
|
||||
$from = $this->fromName ? array($this->fromAddress => $this->fromName) : array($this->fromAddress);
|
||||
$this->recipient = $this->parseAddresses($valueList['recipient']);
|
||||
$this->mailMessage->setSubject($this->subject)->setFrom($from)->setTo($this->recipient)->setPriority($this->priority);
|
||||
$replyTo = $this->replyToName ? array($this->replyToAddress => $this->replyToName) : array($this->replyToAddress);
|
||||
$this->mailMessage->setReplyTo($replyTo);
|
||||
$this->mailMessage->getHeaders()->addTextHeader('Organization', $this->organisation);
|
||||
if ($valueList['recipient_copy']) {
|
||||
$this->mailMessage->setCc($this->parseAddresses($valueList['recipient_copy']));
|
||||
}
|
||||
$this->mailMessage->setCharset($this->characterSet);
|
||||
// Ignore target encoding. This is handled automatically by Swift Mailer and overriding the defaults
|
||||
// is not worth the trouble
|
||||
// Log dirty header lines
|
||||
if ($this->dirtyHeaders) {
|
||||
GeneralUtility::sysLog('Possible misuse of DataSubmissionController: see TYPO3 devLog', 'core', GeneralUtility::SYSLOG_SEVERITY_ERROR);
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']) {
|
||||
GeneralUtility::devLog('DataSubmissionController: ' . GeneralUtility::arrayToLogString($this->dirtyHeaders, '', 200), 'Core', 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks string for suspicious characters
|
||||
*
|
||||
* @param string $string String to check
|
||||
* @return string Valid or empty string
|
||||
*/
|
||||
protected function sanitizeHeaderString($string)
|
||||
{
|
||||
$pattern = '/[\\r\\n\\f\\e]/';
|
||||
if (preg_match($pattern, $string) > 0) {
|
||||
$this->dirtyHeaders[] = $string;
|
||||
$string = '';
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses mailbox headers and turns them into an array.
|
||||
*
|
||||
* Mailbox headers are a comma separated list of 'name <email@example.org' combinations or plain email addresses (or a mix
|
||||
* of these).
|
||||
* The resulting array has key-value pairs where the key is either a number (no display name in the mailbox header) and the
|
||||
* value is the email address, or the key is the email address and the value is the display name.
|
||||
*
|
||||
* @param string $rawAddresses Comma separated list of email addresses (optionally with display name)
|
||||
* @return array Parsed list of addresses.
|
||||
*/
|
||||
protected function parseAddresses($rawAddresses = '')
|
||||
{
|
||||
/** @var $addressParser \TYPO3\CMS\Core\Mail\Rfc822AddressesParser */
|
||||
$addressParser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\Rfc822AddressesParser::class, $rawAddresses);
|
||||
$addresses = $addressParser->parseAddressList();
|
||||
$addressList = array();
|
||||
foreach ($addresses as $address) {
|
||||
if ($address->personal) {
|
||||
// Item with name found ( name <email@example.org> )
|
||||
$addressList[$address->mailbox . '@' . $address->host] = $address->personal;
|
||||
} else {
|
||||
// Item without name found ( email@example.org )
|
||||
$addressList[] = $address->mailbox . '@' . $address->host;
|
||||
}
|
||||
}
|
||||
return $addressList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the actual mail and handles autorespond message
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function sendTheMail()
|
||||
{
|
||||
// Sending the mail requires the recipient and message to be set.
|
||||
if (!$this->mailMessage->getTo() || !trim($this->mailMessage->getBody())) {
|
||||
return false;
|
||||
}
|
||||
$this->mailMessage->send();
|
||||
// Auto response
|
||||
if ($this->autoRespondMessage) {
|
||||
$theParts = explode('/', $this->autoRespondMessage, 2);
|
||||
$theParts[0] = str_replace('###SUBJECT###', $this->subject, $theParts[0]);
|
||||
$theParts[1] = str_replace(
|
||||
array('/', '###MESSAGE###'),
|
||||
array(LF, $this->plainContent),
|
||||
$theParts[1]
|
||||
);
|
||||
/** @var $autoRespondMail \TYPO3\CMS\Core\Mail\MailMessage */
|
||||
$autoRespondMail = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
|
||||
$autoRespondMail->setTo($this->fromAddress)->setSubject($theParts[0])->setFrom($this->recipient)->setBody($theParts[1]);
|
||||
$autoRespondMail->send();
|
||||
}
|
||||
return $this->mailMessage->isSent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do some cleanup at the end (deleting attachment files)
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->temporaryFiles as $file) {
|
||||
if (GeneralUtility::isAllowedAbsPath($file) && GeneralUtility::isFirstPartOfStr($file, PATH_site . 'typo3temp/upload_temp_')) {
|
||||
GeneralUtility::unlink_tempfile($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Controller;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Module\BaseScriptClass;
|
||||
|
||||
/**
|
||||
* The Wizard function in the Web>Info module
|
||||
* Creates a framework for adding wizard sub-sub-modules under the Wizard function in Web>Info
|
||||
*/
|
||||
class WebFunctionWizardsBaseController extends \TYPO3\CMS\Backend\Module\AbstractFunctionModule
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $function_key = 'wiz';
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
* Calls parent init function and then the handleExternalFunctionValue() function from the parent class
|
||||
*
|
||||
* @param BaseScriptClass $pObj A reference to the parent (calling) object (which is probably an instance of an extension class to \TYPO3\CMS\Backend\Module\BaseScriptClass)
|
||||
* @param array $conf The configuration set for this module - from global array TBE_MODULES_EXT
|
||||
* @return void
|
||||
*/
|
||||
public function init(&$pObj, $conf)
|
||||
{
|
||||
// OK, handles ordinary init. This includes setting up the menu array with ->modMenu
|
||||
parent::init($pObj, $conf);
|
||||
$this->handleExternalFunctionValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies parent objects internal MOD_MENU array, adding items this module needs.
|
||||
*
|
||||
* @return array Items merged with the parent objects.
|
||||
*/
|
||||
public function modMenu()
|
||||
{
|
||||
$GLOBALS['LANG']->includeLLFile('EXT:compatibility6/Resources/Private/Language/wizards.xlf');
|
||||
$modMenuAdd = array(
|
||||
$this->function_key => array()
|
||||
);
|
||||
$modMenuAdd[$this->function_key] = $this->pObj->mergeExternalItems($this->pObj->MCONF['name'], $this->function_key, $modMenuAdd[$this->function_key]);
|
||||
$modMenuAdd[$this->function_key] = \TYPO3\CMS\Backend\Utility\BackendUtility::unsetMenuItems(
|
||||
$this->pObj->modTSconfig['properties'],
|
||||
$modMenuAdd[$this->function_key],
|
||||
'menu.' . $this->function_key
|
||||
);
|
||||
return $modMenuAdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creation of the main content. Calling extObjContent() to trigger content generation from the sub-sub modules
|
||||
*
|
||||
* @return string The content
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
$menu = \TYPO3\CMS\Backend\Utility\BackendUtility::getFuncMenu(
|
||||
$this->pObj->id,
|
||||
'SET[wiz]',
|
||||
$this->pObj->MOD_SETTINGS['wiz'],
|
||||
$this->pObj->MOD_MENU['wiz']
|
||||
);
|
||||
|
||||
$content = '';
|
||||
if (!empty($menu)) {
|
||||
$menu = $GLOBALS['LANG']->getLL('wiz_lWizards', true) . ': ' . $menu;
|
||||
$content = '<div>';
|
||||
$content .= '<span class="text-nowrap">' . $menu . '</span>';
|
||||
$content .= '</div>';
|
||||
$content .= '<div style="padding-top: 20px;"></div>';
|
||||
}
|
||||
|
||||
$content .= $this->extObjContent();
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,898 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Controller\Wizard;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* API comments:
|
||||
*
|
||||
* The form wizard can help you to create forms - it allows you to create almost any kind of HTML form elements and in any order and amount.
|
||||
*
|
||||
* The format for the resulting configuration code can be either a line-based configuration. That can look like this:
|
||||
*
|
||||
* Your name: | *name=input | (input your name here!)
|
||||
* Your Email: | *email=input
|
||||
* Your address: | address=textarea,40,10
|
||||
* Your Haircolor: | hair=radio |
|
||||
* upload | attachment=file
|
||||
* | quoted_printable=hidden | 0
|
||||
* | formtype_mail=submit | Send form
|
||||
* | html_enabled=hidden
|
||||
* | subject=hidden | This is the subject
|
||||
*
|
||||
*
|
||||
* Alternatively it can be XML. The same configuration from above looks like this in XML:
|
||||
*
|
||||
* <T3FormWizard>
|
||||
* <n2>
|
||||
* <type>input</type>
|
||||
* <label>Your name:</label>
|
||||
* <required>1</required>
|
||||
* <fieldname>name</fieldname>
|
||||
* <size></size>
|
||||
* <max></max>
|
||||
* <default>(input your name here!)</default>
|
||||
* </n2>
|
||||
* <n4>
|
||||
* <type>input</type>
|
||||
* <label>Your Email:</label>
|
||||
* <required>1</required>
|
||||
* <fieldname>email</fieldname>
|
||||
* <size></size>
|
||||
* <max></max>
|
||||
* <default></default>
|
||||
* </n4>
|
||||
* <n6>
|
||||
* <type>textarea</type>
|
||||
* <label>Your address:</label>
|
||||
* <fieldname>address</fieldname>
|
||||
* <cols>40</cols>
|
||||
* <rows>10</rows>
|
||||
* <default></default>
|
||||
* </n6>
|
||||
* <n8>
|
||||
* <type>radio</type>
|
||||
* <label>Your Haircolor:</label>
|
||||
* <fieldname>hair</fieldname>
|
||||
* <options></options>
|
||||
* </n8>
|
||||
* <n10>
|
||||
* <type>file</type>
|
||||
* <label>upload</label>
|
||||
* <fieldname>attachment</fieldname>
|
||||
* <size></size>
|
||||
* </n10>
|
||||
* <n12>
|
||||
* <type>hidden</type>
|
||||
* <label></label>
|
||||
* <fieldname>quoted_printable</fieldname>
|
||||
* <default>0</default>
|
||||
* </n12>
|
||||
* <n2000>
|
||||
* <fieldname>formtype_mail</fieldname>
|
||||
* <type>submit</type>
|
||||
* <default>Send form</default>
|
||||
* </n2000>
|
||||
* <n2002>
|
||||
* <fieldname>html_enabled</fieldname>
|
||||
* <type>hidden</type>
|
||||
* </n2002>
|
||||
* <n2004>
|
||||
* <fieldname>subject</fieldname>
|
||||
* <type>hidden</type>
|
||||
* <default>This is the subject</default>
|
||||
* </n2004>
|
||||
* <n20>
|
||||
* <content></content>
|
||||
* </n20>
|
||||
* </T3FormWizard>
|
||||
*
|
||||
*
|
||||
* The XML/phpArray structure is the internal format of the wizard.
|
||||
*/
|
||||
class FormsController extends \TYPO3\CMS\Backend\Controller\Wizard\AbstractWizardController
|
||||
{
|
||||
/**
|
||||
* document template object
|
||||
*
|
||||
* @var \TYPO3\CMS\Backend\Template\DocumentTemplate
|
||||
*/
|
||||
public $doc;
|
||||
|
||||
/**
|
||||
* Content accumulation for the module.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $content;
|
||||
|
||||
/**
|
||||
* Used to numerate attachments automatically.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $attachmentCounter = 0;
|
||||
|
||||
/**
|
||||
* If set, the string version of the content is interpreted/written as XML instead of
|
||||
* the original linebased kind. This variable still needs binding to the wizard parameters
|
||||
* - but support is ready!
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $xmlStorage = 0;
|
||||
|
||||
/**
|
||||
* Wizard parameters, coming from TCEforms linking to the wizard.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $P;
|
||||
|
||||
/**
|
||||
* The array which is constantly submitted by the multidimensional form of this wizard.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $FORMCFG;
|
||||
|
||||
/**
|
||||
* Indicates if the form is of a dedicated type, like "formtype_mail" (for tt_content element "Form")
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $special;
|
||||
|
||||
/**
|
||||
* @var IconFactory
|
||||
*/
|
||||
protected $iconFactory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
$this->getLanguageService()->includeLLFile('EXT:compatibility6/Resources/Private/Language/locallang_wizards.xlf');
|
||||
$GLOBALS['SOBE'] = $this;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization the class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
// GPvars:
|
||||
$this->P = GeneralUtility::_GP('P');
|
||||
$this->special = GeneralUtility::_GP('special');
|
||||
$this->FORMCFG = GeneralUtility::_GP('FORMCFG');
|
||||
// Setting options:
|
||||
$this->xmlStorage = $this->P['params']['xmlOutput'];
|
||||
// Document template object:
|
||||
$this->doc = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Template\DocumentTemplate::class);
|
||||
$this->doc->setModuleTemplate('EXT:compatibility6/Resources/Private/Templates/Wizard/Forms.html');
|
||||
// Setting form tag:
|
||||
list($rUri) = explode('#', GeneralUtility::getIndpEnv('REQUEST_URI'));
|
||||
$this->doc->form = '<form action="' . htmlspecialchars($rUri) . '" method="post" name="wizardForm">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects the request object for the current request or subrequest
|
||||
* As this controller goes only through the main() method, it is rather simple for now
|
||||
*
|
||||
* @param ServerRequestInterface $request the current request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface the response with the content
|
||||
*/
|
||||
public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
|
||||
{
|
||||
$this->main();
|
||||
|
||||
$response->getBody()->write($this->content);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function for rendering the form wizard HTML
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
|
||||
$this->content .= '<h2>' . $this->getLanguageService()->getLL('forms_title', true) . '</h2><div>' . $this->formsWizard() . '</div>';
|
||||
} else {
|
||||
$this->content .= '<h2>' . $this->getLanguageService()->getLL('forms_title', true) . '<div><span class="text-danger">' . $this->getLanguageService()->getLL('table_noData', true) . '</span></div>';
|
||||
}
|
||||
// Setting up the buttons and markers for docheader
|
||||
$docHeaderButtons = $this->getButtons();
|
||||
$markers['CSH'] = $docHeaderButtons['csh'];
|
||||
$markers['CONTENT'] = $this->content;
|
||||
// Build the <body> for the module
|
||||
$this->content = $this->doc->startPage('Form Wizard');
|
||||
$this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
|
||||
$this->content .= $this->doc->endPage();
|
||||
$this->content = $this->doc->insertStylesAndJS($this->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputting the accumulated content to screen
|
||||
*
|
||||
* @return void
|
||||
* @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8, use mainAction() instead
|
||||
*/
|
||||
public function printContent()
|
||||
{
|
||||
GeneralUtility::logDeprecatedFunction();
|
||||
echo $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the panel of buttons for submitting the form or otherwise perform operations.
|
||||
*
|
||||
* @return array All available buttons as an assoc. array
|
||||
*/
|
||||
protected function getButtons()
|
||||
{
|
||||
$buttons = array(
|
||||
'csh' => '',
|
||||
'csh_buttons' => '',
|
||||
'close' => '',
|
||||
'save' => '',
|
||||
'save_close' => '',
|
||||
'reload' => ''
|
||||
);
|
||||
if ($this->P['table'] && $this->P['field'] && $this->P['uid']) {
|
||||
// CSH
|
||||
$buttons['csh'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz');
|
||||
// CSH Buttons
|
||||
$buttons['csh_buttons'] = BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_buttons');
|
||||
// Close
|
||||
$buttons['close'] = '<button class="c-inputButton" name="closedok" value="1" title=' . $this->getLanguageService()->sL('LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:closeDoc', true) . '>' . $this->iconFactory->getIcon('actions-document-close', Icon::SIZE_SMALL)->render() . '</button>';
|
||||
// Save
|
||||
$buttons['save'] = '<button class="c-inputButton" name="savedok" value="1" title=' . $this->getLanguageService()->sL('LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:saveDoc', true) . '>' . $this->iconFactory->getIcon('actions-document-save', Icon::SIZE_SMALL)->render() . '</button>';
|
||||
// Save & Close
|
||||
$buttons['save_close'] = '<button class="c-inputButton" name="saveandclosedok" value="1" title=' . $this->getLanguageService()->sL('LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:saveCloseDoc', true) . '>' . $this->iconFactory->getIcon('actions-document-save-close', Icon::SIZE_SMALL)->render() . '</button>';
|
||||
// Reload
|
||||
$buttons['reload'] = '<button class="c-inputButton" name="_refresh" value="1" title="' . $this->getLanguageService()->getLL('forms_refresh', true) . '">' . $this->iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL)->render() . '</button>';
|
||||
}
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the form wizard content
|
||||
*
|
||||
* @return string HTML content for the form.
|
||||
*/
|
||||
public function formsWizard()
|
||||
{
|
||||
if (!$this->checkEditAccess($this->P['table'], $this->P['uid'])) {
|
||||
throw new \RuntimeException('Wizard Error: No access', 1385807526);
|
||||
}
|
||||
// First, check the references by selecting the record:
|
||||
$row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
|
||||
if (!is_array($row)) {
|
||||
throw new \RuntimeException('Wizard Error: No reference to record', 1294587124);
|
||||
}
|
||||
// This will get the content of the form configuration code field to us - possibly
|
||||
// cleaned up, saved to database etc. if the form has been submitted in the meantime.
|
||||
$formCfgArray = $this->getConfigCode($row);
|
||||
// Generation of the Form Wizards HTML code:
|
||||
$content = $this->getFormHTML($formCfgArray, $row);
|
||||
// Return content:
|
||||
return $content;
|
||||
}
|
||||
|
||||
/****************************
|
||||
*
|
||||
* Helper functions
|
||||
*
|
||||
***************************/
|
||||
/**
|
||||
* Will get and return the configuration code string
|
||||
* Will also save (and possibly redirect/exit) the content if a save button has been pressed
|
||||
*
|
||||
* @param array $row Current parent record row (passed by value!)
|
||||
* @return array Configuration Array
|
||||
* @access private
|
||||
*/
|
||||
public function getConfigCode(&$row)
|
||||
{
|
||||
// If some data has been submitted, then construct
|
||||
if (isset($this->FORMCFG['c'])) {
|
||||
// Process incoming:
|
||||
$this->changeFunc();
|
||||
// Convert to string (either line based or XML):
|
||||
if ($this->xmlStorage) {
|
||||
// Convert the input array to XML:
|
||||
$bodyText = GeneralUtility::array2xml_cs($this->FORMCFG['c'], 'T3FormWizard');
|
||||
// Setting cfgArr directly from the input:
|
||||
$cfgArr = $this->FORMCFG['c'];
|
||||
} else {
|
||||
// Convert the input array to a string of configuration code:
|
||||
$bodyText = $this->cfgArray2CfgString($this->FORMCFG['c']);
|
||||
// Create cfgArr from the string based configuration - that way it is cleaned
|
||||
// up and any incompatibilities will be removed!
|
||||
$cfgArr = $this->cfgString2CfgArray($bodyText);
|
||||
}
|
||||
// If a save button has been pressed, then save the new field content:
|
||||
if (isset($_POST['savedok']) || isset($_POST['saveandclosedok'])) {
|
||||
// Make TCEmain object:
|
||||
$tce = GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
|
||||
$tce->stripslashes_values = 0;
|
||||
// Put content into the data array:
|
||||
$data = array();
|
||||
$data[$this->P['table']][$this->P['uid']][$this->P['field']] = $bodyText;
|
||||
if ($this->special == 'formtype_mail') {
|
||||
$data[$this->P['table']][$this->P['uid']]['subheader'] = $this->FORMCFG['recipient'];
|
||||
}
|
||||
// Perform the update:
|
||||
$tce->start($data, array());
|
||||
$tce->process_datamap();
|
||||
// Re-load the record content:
|
||||
$row = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
|
||||
}
|
||||
// If the save/close or close button was pressed, then redirect the screen:
|
||||
if (isset($_POST['saveandclosedok']) || isset($_POST['closedok'])) {
|
||||
\TYPO3\CMS\Core\Utility\HttpUtility::redirect(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl']));
|
||||
}
|
||||
} else {
|
||||
// If nothing has been submitted, load the $bodyText variable from the selected database row:
|
||||
if ($this->xmlStorage) {
|
||||
$cfgArr = GeneralUtility::xml2array($row[$this->P['field']]);
|
||||
} else {
|
||||
// Regular linebased form configuration:
|
||||
$cfgArr = $this->cfgString2CfgArray($row[$this->P['field']]);
|
||||
}
|
||||
$cfgArr = is_array($cfgArr) ? $cfgArr : array();
|
||||
}
|
||||
// Return configuration code:
|
||||
return $cfgArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the HTML for the Form Wizard:
|
||||
*
|
||||
* @param string $formCfgArray Form config array
|
||||
* @param array $row Current parent record array
|
||||
* @return string HTML for the form wizard
|
||||
* @access private
|
||||
*/
|
||||
public function getFormHTML($formCfgArray, $row)
|
||||
{
|
||||
// Initialize variables:
|
||||
$specParts = array();
|
||||
$hiddenFields = array();
|
||||
$tRows = array();
|
||||
// Set header row:
|
||||
$cells = array(
|
||||
$this->getLanguageService()->getLL('forms_preview', true) . ':',
|
||||
$this->getLanguageService()->getLL('forms_element', true) . ':',
|
||||
$this->getLanguageService()->getLL('forms_config', true) . ':'
|
||||
);
|
||||
$tRows[] = '
|
||||
<tr id="typo3-formWizardHeader">
|
||||
<th> </th>
|
||||
<th><strong>' . implode('</strong></th>
|
||||
<th><strong>', $cells) . '</strong></th>
|
||||
</tr>';
|
||||
// Traverse the number of form elements:
|
||||
$k = 0;
|
||||
foreach ($formCfgArray as $confData) {
|
||||
// Initialize:
|
||||
$cells = array();
|
||||
// If there is a configuration line which is active, then render it:
|
||||
if (!isset($confData['comment'])) {
|
||||
// Special parts:
|
||||
if ($this->special == 'formtype_mail' && GeneralUtility::inList('formtype_mail,subject,html_enabled', $confData['fieldname'])) {
|
||||
$specParts[$confData['fieldname']] = $confData['default'];
|
||||
} else {
|
||||
// Render title/field preview COLUMN
|
||||
$cells[] = $confData['type'] != 'hidden' ? '<strong>' . htmlspecialchars($confData['label']) . '</strong>' : '';
|
||||
// Render general type/title COLUMN:
|
||||
$temp_cells = array();
|
||||
// Field type selector:
|
||||
$opt = array();
|
||||
$opt[] = '<option value=""></option>';
|
||||
$types = explode(',', 'input,textarea,select,check,radio,password,file,hidden,submit,property,label');
|
||||
foreach ($types as $t) {
|
||||
$opt[] = '
|
||||
<option value="' . $t . '"' . ($confData['type'] == $t ? ' selected="selected"' : '') . '>' . $this->getLanguageService()->getLL(('forms_type_' . $t), true) . '</option>';
|
||||
}
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_type')] = '
|
||||
<select name="FORMCFG[c][' . ($k + 1) * 2 . '][type]">
|
||||
' . implode('
|
||||
', $opt) . '
|
||||
</select>';
|
||||
// Title field:
|
||||
if (!GeneralUtility::inList('hidden,submit', $confData['type'])) {
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_label')] = '<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][label]" value="' . htmlspecialchars($confData['label']) . '" />';
|
||||
}
|
||||
// Required checkbox:
|
||||
if (!GeneralUtility::inList('check,hidden,submit,label', $confData['type'])) {
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_required')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][required]" value="1"' . ($confData['required'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_required', true) . '" />';
|
||||
}
|
||||
// Put sub-items together into table cell:
|
||||
$cells[] = $this->formatCells($temp_cells);
|
||||
// Render specific field configuration COLUMN:
|
||||
$temp_cells = array();
|
||||
// Fieldname
|
||||
if ($this->special == 'formtype_mail' && $confData['type'] == 'file') {
|
||||
$confData['fieldname'] = 'attachment' . ++$this->attachmentCounter;
|
||||
}
|
||||
if (!GeneralUtility::inList('label', $confData['type'])) {
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_fieldName')] = '<input type="text"' . $this->doc->formWidth(10) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][fieldname]" value="' . htmlspecialchars($confData['fieldname']) . '" title="' . $this->getLanguageService()->getLL('forms_fieldName', true) . '" />';
|
||||
}
|
||||
// Field configuration depending on the fields type:
|
||||
switch ((string)$confData['type']) {
|
||||
case 'textarea':
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_cols')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][cols]" value="' . htmlspecialchars($confData['cols']) . '" title="' . $this->getLanguageService()->getLL('forms_cols', true) . '" />';
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_rows')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][rows]" value="' . htmlspecialchars($confData['rows']) . '" title="' . $this->getLanguageService()->getLL('forms_rows', true) . '" />';
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_extra')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][extra]" value="OFF"' . ($confData['extra'] == 'OFF' ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_extra', true) . '" />';
|
||||
break;
|
||||
case 'input':
|
||||
|
||||
case 'password':
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', true) . '" />';
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_max')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][max]" value="' . htmlspecialchars($confData['max']) . '" title="' . $this->getLanguageService()->getLL('forms_max', true) . '" />';
|
||||
break;
|
||||
case 'file':
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', true) . '" />';
|
||||
break;
|
||||
case 'select':
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_size')] = '<input type="text"' . $this->doc->formWidth(5) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][size]" value="' . htmlspecialchars($confData['size']) . '" title="' . $this->getLanguageService()->getLL('forms_size', true) . '" />';
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_autosize')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][autosize]" value="1"' . ($confData['autosize'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_autosize', true) . '" />';
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_multiple')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][multiple]" value="1"' . ($confData['multiple'] ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_multiple', true) . '" />';
|
||||
break;
|
||||
}
|
||||
// Field configuration depending on the fields type:
|
||||
switch ((string)$confData['type']) {
|
||||
case 'textarea':
|
||||
|
||||
case 'input':
|
||||
|
||||
case 'password':
|
||||
if (trim($confData['specialEval']) !== '') {
|
||||
$hiddenFields[] = '<input type="hidden" name="FORMCFG[c][' . ($k + 1) * 2 . '][specialEval]" value="' . htmlspecialchars($confData['specialEval']) . '" />';
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Default data
|
||||
if ($confData['type'] == 'select' || $confData['type'] == 'radio') {
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_options')] = '<textarea ' . $this->doc->formWidth(15) . ' rows="4" name="FORMCFG[c][' . ($k + 1) * 2 . '][options]" title="' . $this->getLanguageService()->getLL('forms_options', true) . '">' . htmlspecialchars($confData['default']) . '</textarea>';
|
||||
} elseif ($confData['type'] == 'check') {
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_checked')] = '<input type="checkbox" name="FORMCFG[c][' . ($k + 1) * 2 . '][default]" value="1"' . (trim($confData['default']) ? ' checked="checked"' : '') . ' title="' . $this->getLanguageService()->getLL('forms_checked', true) . '" />';
|
||||
} elseif ($confData['type'] && $confData['type'] != 'file') {
|
||||
$temp_cells[$this->getLanguageService()->getLL('forms_default')] = '<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . ($k + 1) * 2 . '][default]" value="' . htmlspecialchars($confData['default']) . '" title="' . $this->getLanguageService()->getLL('forms_default', true) . '" />';
|
||||
}
|
||||
$cells[] = $confData['type'] ? $this->formatCells($temp_cells) : '';
|
||||
// CTRL panel for an item (move up/down/around):
|
||||
$ctrl = '';
|
||||
$onClick = 'document.wizardForm.action+=\'#ANC_' . (($k + 1) * 2 - 2) . '\';';
|
||||
$onClick = ' onclick="' . htmlspecialchars($onClick) . '"';
|
||||
// @todo $inputStyle undefined
|
||||
$brTag = $inputStyle ? '' : '<br />';
|
||||
if ($k != 1) {
|
||||
$ctrl .= '<button name="FORMCFG[row_top][' . ($k + 1) * 2 . ']"' . $onClick . ' title="' . $this->getLanguageService()->getLL('table_top', true) . '">' . $this->iconFactory->getIcon('actions-move-to-top', Icon::SIZE_SMALL)->render() . '</button>' . $brTag;
|
||||
$ctrl .= '<button name="FORMCFG[row_up][' . ($k + 1) * 2 . ']"' . $onClick . ' title="' . $this->getLanguageService()->getLL('table_up', true) . '">' . $this->iconFactory->getIcon('actions-move-up', Icon::SIZE_SMALL)->render() . '</button>' . $brTag;
|
||||
}
|
||||
$ctrl .= '<button name="FORMCFG[row_remove][' . ($k + 1) * 2 . ']" ' . $onClick . ' title = "' . $this->getLanguageService()->getLL('table_removeRow', true) . '">' . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '</button>' . $brTag;
|
||||
|
||||
if ($k != (count($formCfgArray)/2)) {
|
||||
$ctrl .= '<button name="FORMCFG[row_down][' . ($k + 1) * 2 . ']"' . $onClick . ' title="' . $this->getLanguageService()->getLL('table_down', true) . '">' . $this->iconFactory->getIcon('actions-move-down', Icon::SIZE_SMALL)->render() . '</button>' . $brTag;
|
||||
$ctrl .= '<button name="FORMCFG[row_bottom][' . ($k + 1) * 2 . ']"' . $onClick . ' title="' . $this->getLanguageService()->getLL('table_bottom', true) . '">' . $this->iconFactory->getIcon('actions-move-to-bottom', Icon::SIZE_SMALL)->render() . '</button>' . $brTag;
|
||||
}
|
||||
|
||||
$ctrl .= '<button name="FORMCFG[row_add][' . ($k + 1) * 2 . ']"' . $onClick . ' title="' . $this->getLanguageService()->getLL('table_addRow', true) . '">' . $this->iconFactory->getIcon('actions-template-new', Icon::SIZE_SMALL)->render() . '</button>' . $brTag;
|
||||
$ctrl = '<span class="c-wizButtonsV">' . $ctrl . '</span>';
|
||||
// Finally, put together the full row from the generated content above:
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<td><a name="ANC_' . ($k + 1) * 2 . '"></a>' . $ctrl . '</td>
|
||||
<td>' . implode('</td>
|
||||
<td valign="top">', $cells) . '</td>
|
||||
</tr>';
|
||||
}
|
||||
} else {
|
||||
$hiddenFields[] = '<input type="hidden" name="FORMCFG[c][' . ($k + 1) * 2 . '][comment]" value="' . htmlspecialchars($confData['comment']) . '" />';
|
||||
}
|
||||
// Increment counter:
|
||||
$k++;
|
||||
}
|
||||
// If the form is of the special type "formtype_mail" (used for tt_content elements):
|
||||
if ($this->special == 'formtype_mail') {
|
||||
// Blank spacer:
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<td colspan="4"> </td>
|
||||
</tr>';
|
||||
// Header:
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<th colspan="4"><h4>' . $this->getLanguageService()->getLL('forms_special_eform', true) . ': ' . BackendUtility::cshItem('xMOD_csh_corebe', 'wizard_forms_wiz_formmail_info') . '</h4></th>
|
||||
</tr>';
|
||||
// "FORM type":
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
<td>' . $this->getLanguageService()->getLL('forms_eform_formtype_mail', true) . ':</td>
|
||||
<td>
|
||||
<input type="hidden" name="FORMCFG[c][' . 1000 * 2 . '][fieldname]" value="formtype_mail" />
|
||||
<input type="hidden" name="FORMCFG[c][' . 1000 * 2 . '][type]" value="submit" />
|
||||
<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . 1000 * 2 . '][default]" value="' . htmlspecialchars($specParts['formtype_mail']) . '" />
|
||||
</td>
|
||||
</tr>';
|
||||
// "Send HTML mail":
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
<td>' . $this->getLanguageService()->getLL('forms_eform_html_enabled', true) . ':</td>
|
||||
<td>
|
||||
<input type="hidden" name="FORMCFG[c][' . 1001 * 2 . '][fieldname]" value="html_enabled" />
|
||||
<input type="hidden" name="FORMCFG[c][' . 1001 * 2 . '][type]" value="hidden" />
|
||||
<input type="checkbox" name="FORMCFG[c][' . 1001 * 2 . '][default]" value="1"' . ($specParts['html_enabled'] ? ' checked="checked"' : '') . ' />
|
||||
</td>
|
||||
</tr>';
|
||||
// "Subject":
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
<td>' . $this->getLanguageService()->getLL('forms_eform_subject', true) . ':</td>
|
||||
<td>
|
||||
<input type="hidden" name="FORMCFG[c][' . 1002 * 2 . '][fieldname]" value="subject" />
|
||||
<input type="hidden" name="FORMCFG[c][' . 1002 * 2 . '][type]" value="hidden" />
|
||||
<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[c][' . 1002 * 2 . '][default]" value="' . htmlspecialchars($specParts['subject']) . '" />
|
||||
</td>
|
||||
</tr>';
|
||||
// Recipient:
|
||||
$tRows[] = '
|
||||
<tr>
|
||||
<td colspan="2"> </td>
|
||||
<td>' . $this->getLanguageService()->getLL('forms_eform_recipient', true) . ':</td>
|
||||
<td>
|
||||
<input type="text"' . $this->doc->formWidth(15) . ' name="FORMCFG[recipient]" value="' . htmlspecialchars($row['subheader']) . '" />
|
||||
</td>
|
||||
</tr>';
|
||||
}
|
||||
$content = '';
|
||||
// Implode all table rows into a string, wrapped in table tags.
|
||||
$content .= '
|
||||
|
||||
<!--
|
||||
Form wizard
|
||||
-->
|
||||
<table class="table table-bordered table-condensed" id="typo3-formwizard">
|
||||
' . implode('', $tRows) . '
|
||||
</table>';
|
||||
// Add hidden fields:
|
||||
$content .= implode('', $hiddenFields);
|
||||
// Return content:
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if a control button (up/down/around/delete) has been pressed for an item and accordingly it will manipulate the internal FORMCFG array
|
||||
*
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
public function changeFunc()
|
||||
{
|
||||
if ($this->FORMCFG['row_remove']) {
|
||||
$kk = key($this->FORMCFG['row_remove']);
|
||||
$cmd = 'row_remove';
|
||||
} elseif ($this->FORMCFG['row_add']) {
|
||||
$kk = key($this->FORMCFG['row_add']);
|
||||
$cmd = 'row_add';
|
||||
} elseif ($this->FORMCFG['row_top']) {
|
||||
$kk = key($this->FORMCFG['row_top']);
|
||||
$cmd = 'row_top';
|
||||
} elseif ($this->FORMCFG['row_bottom']) {
|
||||
$kk = key($this->FORMCFG['row_bottom']);
|
||||
$cmd = 'row_bottom';
|
||||
} elseif ($this->FORMCFG['row_up']) {
|
||||
$kk = key($this->FORMCFG['row_up']);
|
||||
$cmd = 'row_up';
|
||||
} elseif ($this->FORMCFG['row_down']) {
|
||||
$kk = key($this->FORMCFG['row_down']);
|
||||
$cmd = 'row_down';
|
||||
}
|
||||
if ($cmd && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($kk)) {
|
||||
if (substr($cmd, 0, 4) == 'row_') {
|
||||
switch ($cmd) {
|
||||
case 'row_remove':
|
||||
unset($this->FORMCFG['c'][$kk]);
|
||||
break;
|
||||
case 'row_add':
|
||||
$this->FORMCFG['c'][$kk + 1] = array();
|
||||
break;
|
||||
case 'row_top':
|
||||
$this->FORMCFG['c'][1] = $this->FORMCFG['c'][$kk];
|
||||
unset($this->FORMCFG['c'][$kk]);
|
||||
break;
|
||||
case 'row_bottom':
|
||||
$this->FORMCFG['c'][1000000] = $this->FORMCFG['c'][$kk];
|
||||
unset($this->FORMCFG['c'][$kk]);
|
||||
break;
|
||||
case 'row_up':
|
||||
$this->FORMCFG['c'][$kk - 3] = $this->FORMCFG['c'][$kk];
|
||||
unset($this->FORMCFG['c'][$kk]);
|
||||
break;
|
||||
case 'row_down':
|
||||
$this->FORMCFG['c'][$kk + 3] = $this->FORMCFG['c'][$kk];
|
||||
unset($this->FORMCFG['c'][$kk]);
|
||||
break;
|
||||
}
|
||||
ksort($this->FORMCFG['c']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the input array to a configuration code string
|
||||
*
|
||||
* @param array $cfgArr Array of form configuration (follows the input structure from the form wizard POST form)
|
||||
* @return string The array converted into a string with line-based configuration.
|
||||
* @see cfgString2CfgArray()
|
||||
*/
|
||||
public function cfgArray2CfgString($cfgArr)
|
||||
{
|
||||
// Initialize:
|
||||
$inLines = array();
|
||||
// Traverse the elements of the form wizard and transform the settings into configuration code.
|
||||
foreach ($cfgArr as $vv) {
|
||||
// If "content" is found, then just pass it over.
|
||||
if ($vv['comment']) {
|
||||
$inLines[] = trim($vv['comment']);
|
||||
} else {
|
||||
// Begin to put together the single-line configuration code of this field:
|
||||
// Reset:
|
||||
$thisLine = array();
|
||||
// Set Label:
|
||||
$thisLine[0] = str_replace('|', '', $vv['label']);
|
||||
// Set Type:
|
||||
if ($vv['type']) {
|
||||
$thisLine[1] = ($vv['required'] ? '*' : '') . str_replace(',', '', (($vv['fieldname'] ? $vv['fieldname'] . '=' : '') . $vv['type']));
|
||||
// Default:
|
||||
$tArr = array('', '', '', '', '', '');
|
||||
switch ((string)$vv['type']) {
|
||||
case 'textarea':
|
||||
if ((int)$vv['cols']) {
|
||||
$tArr[0] = (int)$vv['cols'];
|
||||
}
|
||||
if ((int)$vv['rows']) {
|
||||
$tArr[1] = (int)$vv['rows'];
|
||||
}
|
||||
if (trim($vv['extra'])) {
|
||||
$tArr[2] = trim($vv['extra']);
|
||||
}
|
||||
if ($vv['specialEval'] !== '') {
|
||||
// Preset blank default value so position 3 can get a value...
|
||||
$thisLine[2] = '';
|
||||
$thisLine[3] = $vv['specialEval'];
|
||||
}
|
||||
break;
|
||||
case 'input':
|
||||
case 'password':
|
||||
if ((int)$vv['size']) {
|
||||
$tArr[0] = (int)$vv['size'];
|
||||
}
|
||||
if ((int)$vv['max']) {
|
||||
$tArr[1] = (int)$vv['max'];
|
||||
}
|
||||
if ($vv['specialEval'] !== '') {
|
||||
// Preset blank default value so position 3 can get a value...
|
||||
$thisLine[2] = '';
|
||||
$thisLine[3] = $vv['specialEval'];
|
||||
}
|
||||
break;
|
||||
case 'file':
|
||||
if ((int)$vv['size']) {
|
||||
$tArr[0] = (int)$vv['size'];
|
||||
}
|
||||
break;
|
||||
case 'select':
|
||||
if ((int)$vv['size']) {
|
||||
$tArr[0] = (int)$vv['size'];
|
||||
}
|
||||
if ($vv['autosize']) {
|
||||
$tArr[0] = 'auto';
|
||||
}
|
||||
if ($vv['multiple']) {
|
||||
$tArr[1] = 'm';
|
||||
}
|
||||
break;
|
||||
}
|
||||
$tArr = $this->cleanT($tArr);
|
||||
if (!empty($tArr)) {
|
||||
$thisLine[1] .= ',' . implode(',', $tArr);
|
||||
}
|
||||
$thisLine[1] = str_replace('|', '', $thisLine[1]);
|
||||
// Default:
|
||||
if ($vv['type'] == 'select' || $vv['type'] == 'radio') {
|
||||
$options = str_replace(',', '', $vv['options']);
|
||||
$options = str_replace(
|
||||
array(CRLF, CR, LF),
|
||||
', ',
|
||||
$options);
|
||||
$thisLine[2] = $options;
|
||||
} elseif ($vv['type'] == 'check') {
|
||||
if ($vv['default']) {
|
||||
$thisLine[2] = 1;
|
||||
}
|
||||
} elseif (trim($vv['default']) !== '') {
|
||||
$thisLine[2] = $vv['default'];
|
||||
}
|
||||
if (isset($thisLine[2])) {
|
||||
$thisLine[2] = str_replace('|', '', $thisLine[2]);
|
||||
}
|
||||
}
|
||||
// Compile the final line:
|
||||
$inLines[] = preg_replace('/[
|
||||
|
||||
]*/', '', implode(' | ', $thisLine));
|
||||
}
|
||||
}
|
||||
// Finally, implode the lines into a string, and return it:
|
||||
return implode(LF, $inLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the input configuration code string into an array
|
||||
*
|
||||
* @param string $cfgStr Configuration code
|
||||
* @return array Configuration array
|
||||
* @see cfgArray2CfgString()
|
||||
*/
|
||||
public function cfgString2CfgArray($cfgStr)
|
||||
{
|
||||
// Traverse the number of form elements:
|
||||
$tLines = explode(LF, $cfgStr);
|
||||
$attachmentCounter = 0;
|
||||
foreach ($tLines as $k => $v) {
|
||||
// Initialize:
|
||||
$confData = array();
|
||||
$val = trim($v);
|
||||
// Accept a line as configuration if a) it is blank(! - because blank lines indicates new,
|
||||
// unconfigured fields) or b) it is NOT a comment.
|
||||
if (!$val || strcspn($val, '#/')) {
|
||||
// Split:
|
||||
$parts = GeneralUtility::trimExplode('|', $val);
|
||||
// Label:
|
||||
$confData['label'] = trim($parts[0]);
|
||||
// Field:
|
||||
$fParts = GeneralUtility::trimExplode(',', $parts[1]);
|
||||
$fParts[0] = trim($fParts[0]);
|
||||
if ($fParts[0][0] === '*') {
|
||||
$confData['required'] = 1;
|
||||
$fParts[0] = substr($fParts[0], 1);
|
||||
}
|
||||
$typeParts = GeneralUtility::trimExplode('=', $fParts[0]);
|
||||
$confData['type'] = trim(strtolower(end($typeParts)));
|
||||
if ($confData['type']) {
|
||||
if (count($typeParts) === 1) {
|
||||
$confData['fieldname'] = substr(preg_replace('/[^a-zA-Z0-9_]/', '', str_replace(' ', '_', trim($parts[0]))), 0, 30);
|
||||
// Attachment names...
|
||||
if ($confData['type'] == 'file') {
|
||||
$confData['fieldname'] = 'attachment' . $attachmentCounter;
|
||||
$attachmentCounter = (int)$attachmentCounter + 1;
|
||||
}
|
||||
} else {
|
||||
$confData['fieldname'] = str_replace(' ', '_', trim($typeParts[0]));
|
||||
}
|
||||
switch ((string)$confData['type']) {
|
||||
case 'select':
|
||||
case 'radio':
|
||||
$confData['default'] = implode(LF, GeneralUtility::trimExplode(',', $parts[2]));
|
||||
break;
|
||||
default:
|
||||
$confData['default'] = trim($parts[2]);
|
||||
}
|
||||
// Field configuration depending on the fields type:
|
||||
switch ((string)$confData['type']) {
|
||||
case 'textarea':
|
||||
$confData['cols'] = $fParts[1];
|
||||
$confData['rows'] = $fParts[2];
|
||||
$confData['extra'] = strtoupper($fParts[3]) == 'OFF' ? 'OFF' : '';
|
||||
$confData['specialEval'] = trim($parts[3]);
|
||||
break;
|
||||
case 'input':
|
||||
case 'password':
|
||||
$confData['size'] = $fParts[1];
|
||||
$confData['max'] = $fParts[2];
|
||||
$confData['specialEval'] = trim($parts[3]);
|
||||
break;
|
||||
case 'file':
|
||||
$confData['size'] = $fParts[1];
|
||||
break;
|
||||
case 'select':
|
||||
$confData['size'] = (int)$fParts[1] ? $fParts[1] : '';
|
||||
$confData['autosize'] = strtolower(trim($fParts[1])) === 'auto' ? 1 : 0;
|
||||
$confData['multiple'] = strtolower(trim($fParts[2])) === 'm' ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No configuration, only a comment:
|
||||
$confData = array(
|
||||
'comment' => $val
|
||||
);
|
||||
}
|
||||
// Adding config array:
|
||||
$cfgArr[] = $confData;
|
||||
}
|
||||
// Return cfgArr
|
||||
return $cfgArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any "trailing elements" in the array which consists of whitespace (little like trim() does for strings, so this does for arrays)
|
||||
*
|
||||
* @param array $tArr Single dim array
|
||||
* @return array Processed array
|
||||
* @access private
|
||||
*/
|
||||
public function cleanT($tArr)
|
||||
{
|
||||
for ($a = count($tArr); $a > 0; $a--) {
|
||||
if ((string)$tArr[$a - 1] !== '') {
|
||||
break;
|
||||
} else {
|
||||
unset($tArr[$a - 1]);
|
||||
}
|
||||
}
|
||||
return $tArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps items in $fArr in table cells/rows, displaying them vertically.
|
||||
*
|
||||
* @param array $fArr Array of label/HTML pairs.
|
||||
* @return string HTML table
|
||||
* @access private
|
||||
*/
|
||||
public function formatCells($fArr)
|
||||
{
|
||||
// Traverse the elements in $fArr and wrap them in table cells:
|
||||
$lines = array();
|
||||
foreach ($fArr as $l => $c) {
|
||||
$lines[] = '
|
||||
<tr>
|
||||
<td nowrap="nowrap">' . htmlspecialchars(($l . ':')) . ' </td>
|
||||
<td>' . $c . '</td>
|
||||
</tr>';
|
||||
}
|
||||
$lines[] = '
|
||||
<tr>
|
||||
<td colspan="2"></td>
|
||||
</tr>';
|
||||
// Wrap in table and return:
|
||||
return '
|
||||
<table>
|
||||
' . implode('', $lines) . '
|
||||
</table>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Form\Container;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Form\Container\AbstractContainer;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Lang\LanguageService;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
|
||||
/**
|
||||
* The container handles single elements.
|
||||
*
|
||||
* This one is called by FlexFormTabsContainer, FlexFormNoTabsContainer or FlexFormContainerContainer.
|
||||
* For single fields, the code is similar to SingleFieldContainer, processing will end up in single
|
||||
* element classes depending on specific type of an element. Additionally, it determines if a
|
||||
* section is handled and hands over to FlexFormSectionContainer in this case.
|
||||
*/
|
||||
class FlexFormElementContainer extends AbstractContainer
|
||||
{
|
||||
/**
|
||||
* Entry method
|
||||
*
|
||||
* @return array As defined in initializeResultArray() of AbstractNode
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$table = $this->data['tableName'];
|
||||
$row = $this->data['databaseRow'];
|
||||
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
|
||||
$flexFormRowData = $this->data['flexFormRowData'];
|
||||
$flexFormFormPrefix = $this->data['flexFormFormPrefix'];
|
||||
$parameterArray = $this->data['parameterArray'];
|
||||
$metaData = $this->data['parameterArray']['fieldConf']['config']['ds']['meta'];
|
||||
|
||||
$languageService = $this->getLanguageService();
|
||||
/** @var IconFactory $iconFactory */
|
||||
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
$resultArray = $this->initializeResultArray();
|
||||
foreach ($flexFormDataStructureArray as $flexFormFieldName => $flexFormFieldArray) {
|
||||
if (
|
||||
// No item array found at all
|
||||
!is_array($flexFormFieldArray)
|
||||
// Not a section or container and not a list of single items
|
||||
|| (!isset($flexFormFieldArray['type']) && !is_array($flexFormFieldArray['config']))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($flexFormFieldArray['type'] === 'array') {
|
||||
// Section
|
||||
if (empty($flexFormFieldArray['section'])) {
|
||||
$resultArray['html'] = LF . 'Section expected at ' . $flexFormFieldName . ' but not found';
|
||||
continue;
|
||||
}
|
||||
|
||||
$sectionTitle = '';
|
||||
if (!empty($flexFormFieldArray['title'])) {
|
||||
$sectionTitle = $languageService->sL($flexFormFieldArray['title']);
|
||||
}
|
||||
|
||||
$options = $this->data;
|
||||
$options['flexFormDataStructureArray'] = $flexFormFieldArray['el'];
|
||||
$options['flexFormRowData'] = is_array($flexFormRowData[$flexFormFieldName]['el']) ? $flexFormRowData[$flexFormFieldName]['el'] : array();
|
||||
$options['flexFormSectionType'] = $flexFormFieldName;
|
||||
$options['flexFormSectionTitle'] = $sectionTitle;
|
||||
$options['renderType'] = 'flexFormSectionContainer';
|
||||
$sectionContainerResult = $this->nodeFactory->create($options)->render();
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $sectionContainerResult);
|
||||
} else {
|
||||
if (is_array($metaData) && isset($metaData['langChildren']) && isset($metaData['languagesOnElement'])) {
|
||||
$lkeys = $metaData['languagesOnElement'];
|
||||
array_walk($lkeys, function (&$value) {
|
||||
$value = 'v' . $value;
|
||||
});
|
||||
} else {
|
||||
$lkeys = array('vDEF');
|
||||
}
|
||||
$html = array();
|
||||
foreach ($lkeys as $lkey) {
|
||||
// Set up options for single element
|
||||
$fakeParameterArray = array(
|
||||
'fieldConf' => array(
|
||||
'label' => $languageService->sL(trim($flexFormFieldArray['label'])),
|
||||
'config' => $flexFormFieldArray['config'],
|
||||
'defaultExtras' => $flexFormFieldArray['defaultExtras'],
|
||||
'onChange' => $flexFormFieldArray['onChange'],
|
||||
),
|
||||
);
|
||||
|
||||
$alertMsgOnChange = '';
|
||||
if (
|
||||
$fakeParameterArray['fieldConf']['onChange'] === 'reload'
|
||||
|| !empty($GLOBALS['TCA'][$table]['ctrl']['type']) && $GLOBALS['TCA'][$table]['ctrl']['type'] === $flexFormFieldName
|
||||
|| !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate']) && GeneralUtility::inList($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'], $flexFormFieldName)
|
||||
) {
|
||||
if ($this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
|
||||
$alertMsgOnChange = 'top.TYPO3.Modal.confirm(TBE_EDITOR.labels.refreshRequired.title, TBE_EDITOR.labels.refreshRequired.content).on("button.clicked", function(e) { if (e.target.name == "ok" && TBE_EDITOR.checkSubmit(-1)) { TBE_EDITOR.submitForm() } top.TYPO3.Modal.dismiss(); });';
|
||||
} else {
|
||||
$alertMsgOnChange = 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm();}';
|
||||
}
|
||||
}
|
||||
$fakeParameterArray['fieldChangeFunc'] = $parameterArray['fieldChangeFunc'];
|
||||
if ($alertMsgOnChange) {
|
||||
$fakeParameterArray['fieldChangeFunc']['alert'] = $alertMsgOnChange;
|
||||
}
|
||||
|
||||
$fakeParameterArray['onFocus'] = $parameterArray['onFocus'];
|
||||
$fakeParameterArray['label'] = $parameterArray['label'];
|
||||
$fakeParameterArray['itemFormElName'] = $parameterArray['itemFormElName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
|
||||
$fakeParameterArray['itemFormElID'] = $fakeParameterArray['itemFormElName'];
|
||||
if (isset($flexFormRowData[$flexFormFieldName][$lkey])) {
|
||||
$fakeParameterArray['itemFormElValue'] = $flexFormRowData[$flexFormFieldName][$lkey];
|
||||
} else {
|
||||
$fakeParameterArray['itemFormElValue'] = $fakeParameterArray['fieldConf']['config']['default'];
|
||||
}
|
||||
|
||||
$options = $this->data;
|
||||
$options['parameterArray'] = $fakeParameterArray;
|
||||
$options['elementBaseName'] = $this->data['elementBaseName'] . $flexFormFormPrefix . '[' . $flexFormFieldName . '][' . $lkey . ']';
|
||||
|
||||
if (!empty($flexFormFieldArray['config']['renderType'])) {
|
||||
$options['renderType'] = $flexFormFieldArray['config']['renderType'];
|
||||
} else {
|
||||
// Fallback to type if no renderType is given
|
||||
$options['renderType'] = $flexFormFieldArray['config']['type'];
|
||||
}
|
||||
$childResult = $this->nodeFactory->create($options)->render();
|
||||
|
||||
$theTitle = htmlspecialchars($fakeParameterArray['fieldConf']['label']);
|
||||
$defInfo = array();
|
||||
|
||||
// Possible line breaks in the label through xml: \n => <br/>, usage of nl2br() not possible, so it's done through str_replace (?!)
|
||||
$processedTitle = str_replace('\\n', '<br />', $theTitle);
|
||||
// @todo: Similar to the processing within SingleElementContainer ... use it from there?!
|
||||
$html[] = '<div class="form-group t3js-formengine-palette-field t3js-formengine-validation-marker">';
|
||||
$html[] = '<label class="t3js-formengine-label">';
|
||||
if (is_array($metaData) && isset($metaData['langChildren']) && $metaData['langChildren']) {
|
||||
// Find language uid of this iso code
|
||||
$languageUid = 0;
|
||||
$lKeyWithoutV = substr($lkey, 1);
|
||||
if ($lKeyWithoutV !== 'DEF') {
|
||||
foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
|
||||
if ($systemLanguageRow['iso'] === $lKeyWithoutV) {
|
||||
$languageUid = $systemLanguageRow['uid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$languageIcon = $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render();
|
||||
$html[] = $languageIcon;
|
||||
}
|
||||
$html[] = BackendUtility::wrapInHelp($parameterArray['_cshKey'], $flexFormFieldName, $processedTitle);
|
||||
$html[] = '</label>';
|
||||
$html[] = '<div class="t3js-formengine-field-item">';
|
||||
$html[] = $childResult['html'];
|
||||
$html[] = implode(LF, $defInfo);
|
||||
$html[] = $this->renderVDEFDiff($flexFormRowData[$flexFormFieldName], $lkey);
|
||||
$html[] = '</div>';
|
||||
$html[] = '</div>';
|
||||
}
|
||||
|
||||
if (!empty($html)) {
|
||||
$resultArray['html'] .= '<div class="form-section">' . implode(LF, $html) . '</div>';
|
||||
}
|
||||
$childResult['html'] = '';
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult);
|
||||
}
|
||||
}
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the diff-view of vDEF fields in flex forms
|
||||
*
|
||||
* @param array $vArray Record array of the record being edited
|
||||
* @param string $vDEFkey HTML of the form field. This is what we add the content to.
|
||||
* @return string Item string returned again, possibly with the original value added to.
|
||||
*/
|
||||
protected function renderVDEFDiff($vArray, $vDEFkey)
|
||||
{
|
||||
$item = null;
|
||||
if (
|
||||
$GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase'] && isset($vArray[$vDEFkey . '.vDEFbase'])
|
||||
&& (string)$vArray[$vDEFkey . '.vDEFbase'] !== (string)$vArray['vDEF'][0]
|
||||
) {
|
||||
// Create diff-result:
|
||||
$diffUtility = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Utility\DiffUtility::class);
|
||||
$diffres = $diffUtility->makeDiffDisplay($vArray[$vDEFkey . '.vDEFbase'], $vArray['vDEF']);
|
||||
$item = '<div class="typo3-TCEforms-diffBox">' . '<div class="typo3-TCEforms-diffBox-header">'
|
||||
. htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:labels.changeInOrig')) . ':</div>' . $diffres . '</div>';
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService()
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUserAuthentication()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Form\Container;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Form\Container\AbstractContainer;
|
||||
use TYPO3\CMS\Core\Imaging\Icon;
|
||||
use TYPO3\CMS\Core\Imaging\IconFactory;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Entry container to a flex form element. This container is created by
|
||||
* SingleFieldContainer if a type='flex' field is rendered.
|
||||
*
|
||||
* It either forks a FlexFormTabsContainer or a FlexFormNoTabsContainer.
|
||||
*
|
||||
* This container additionally handles flex form languages on sheet level.
|
||||
*/
|
||||
class FlexFormEntryContainer extends AbstractContainer
|
||||
{
|
||||
/**
|
||||
* Entry method
|
||||
*
|
||||
* @return array As defined in initializeResultArray() of AbstractNode
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$flexFormDataStructureArray = $this->data['parameterArray']['fieldConf']['config']['ds'];
|
||||
$flexFormRowData = $this->data['parameterArray']['itemFormElValue'];
|
||||
|
||||
/** @var IconFactory $iconFactory */
|
||||
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
|
||||
|
||||
// Tabs or no tabs - that's the question
|
||||
$hasTabs = false;
|
||||
if (count($flexFormDataStructureArray['sheets']) > 1) {
|
||||
$hasTabs = true;
|
||||
}
|
||||
|
||||
$resultArray = $this->initializeResultArray();
|
||||
|
||||
foreach ($flexFormDataStructureArray['meta']['languagesOnSheetLevel'] as $lKey) {
|
||||
// Add language as header
|
||||
if (!$flexFormDataStructureArray['meta']['langChildren'] && !$flexFormDataStructureArray['meta']['langDisable']) {
|
||||
// Find language uid of this iso code
|
||||
$languageUid = 0;
|
||||
if ($lKey !== 'DEF') {
|
||||
foreach ($this->data['systemLanguageRows'] as $systemLanguageRow) {
|
||||
if ($systemLanguageRow['iso'] === $lKey) {
|
||||
$languageUid = $systemLanguageRow['uid'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$resultArray['html'] .= LF
|
||||
. '<strong>'
|
||||
. $iconFactory->getIcon($this->data['systemLanguageRows'][$languageUid]['flagIconIdentifier'], Icon::SIZE_SMALL)->render()
|
||||
. htmlspecialchars($this->data['systemLanguageRows'][$languageUid]['title'])
|
||||
. '</strong>';
|
||||
}
|
||||
|
||||
// Default language "lDEF", other options are "lUK" or whatever country code
|
||||
$flexFormCurrentLanguage = 'l' . $lKey;
|
||||
|
||||
$options = $this->data;
|
||||
$options['flexFormCurrentLanguage'] = $flexFormCurrentLanguage;
|
||||
$options['flexFormDataStructureArray'] = $flexFormDataStructureArray;
|
||||
$options['flexFormRowData'] = $flexFormRowData;
|
||||
if (!$hasTabs) {
|
||||
$options['renderType'] = 'flexFormNoTabsContainer';
|
||||
$flexFormNoTabsResult = $this->nodeFactory->create($options)->render();
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormNoTabsResult);
|
||||
} else {
|
||||
$options['renderType'] = 'flexFormTabsContainer';
|
||||
$flexFormTabsContainerResult = $this->nodeFactory->create($options)->render();
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $flexFormTabsContainerResult);
|
||||
}
|
||||
}
|
||||
$resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/FormEngineFlexForm';
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Form\Container;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Form\Container\AbstractContainer;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Handle a flex form that has no tabs.
|
||||
*
|
||||
* This container is called by FlexFormEntryContainer if only a default sheet
|
||||
* exists. It evaluates the display condition and hands over rendering of single
|
||||
* fields to FlexFormElementContainer.
|
||||
*/
|
||||
class FlexFormNoTabsContainer extends AbstractContainer
|
||||
{
|
||||
/**
|
||||
* Entry method
|
||||
*
|
||||
* @return array As defined in initializeResultArray() of AbstractNode
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$table = $this->data['tableName'];
|
||||
$row = $this->data['databaseRow'];
|
||||
$fieldName = $this->data['fieldName']; // field name of the flex form field in DB
|
||||
$parameterArray = $this->data['parameterArray'];
|
||||
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
|
||||
$flexFormCurrentLanguage = $this->data['flexFormCurrentLanguage'];
|
||||
$flexFormRowData = $this->data['flexFormRowData'];
|
||||
$resultArray = $this->initializeResultArray();
|
||||
|
||||
// Flex ds was normalized in flex provider to always have a sheet.
|
||||
// Determine this single sheet name, most often it ends up with sDEF, except if only one sheet was defined
|
||||
$sheetName = array_pop(array_keys($flexFormDataStructureArray['sheets']));
|
||||
$flexFormRowDataSubPart = $flexFormRowData['data'][$sheetName][$flexFormCurrentLanguage];
|
||||
|
||||
// That was taken from GeneralUtility::resolveSheetDefInDS - no idea if it is important
|
||||
unset($flexFormDataStructureArray['meta']);
|
||||
|
||||
if (!is_array($flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'])) {
|
||||
$resultArray['html'] = 'Data Structure ERROR: No [\'ROOT\'][\'el\'] element found in flex form definition.';
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
// Assemble key for loading the correct CSH file
|
||||
// @todo: what is that good for? That is for the title of single elements ... see FlexFormElementContainer!
|
||||
$dsPointerFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['ds_pointerField'], true);
|
||||
$parameterArray['_cshKey'] = $table . '.' . $fieldName;
|
||||
foreach ($dsPointerFields as $key) {
|
||||
if ((string)$row[$key] !== '') {
|
||||
$parameterArray['_cshKey'] .= '.' . $row[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$options = $this->data;
|
||||
$options['flexFormDataStructureArray'] = $flexFormDataStructureArray['sheets'][$sheetName]['ROOT']['el'];
|
||||
$options['flexFormRowData'] = $flexFormRowDataSubPart;
|
||||
$options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
|
||||
$options['parameterArray'] = $parameterArray;
|
||||
|
||||
$options['renderType'] = 'flexFormElementContainer';
|
||||
return $this->nodeFactory->create($options)->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Form\Container;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Form\Container\AbstractContainer;
|
||||
use TYPO3\CMS\Backend\Template\DocumentTemplate;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Lang\LanguageService;
|
||||
|
||||
/**
|
||||
* Handle flex forms that have tabs (multiple "sheets").
|
||||
*
|
||||
* This container is called by FlexFormEntryContainer. It resolves each
|
||||
* sheet and hands rendering of single sheet content over to FlexFormElementContainer.
|
||||
*/
|
||||
class FlexFormTabsContainer extends AbstractContainer
|
||||
{
|
||||
/**
|
||||
* Entry method
|
||||
*
|
||||
* @return array As defined in initializeResultArray() of AbstractNode
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$languageService = $this->getLanguageService();
|
||||
|
||||
$table = $this->data['tableName'];
|
||||
$row = $this->data['databaseRow'];
|
||||
$fieldName = $this->data['fieldName']; // field name of the flex form field in DB
|
||||
$parameterArray = $this->data['parameterArray'];
|
||||
$flexFormDataStructureArray = $this->data['flexFormDataStructureArray'];
|
||||
$flexFormCurrentLanguage = $this->data['flexFormCurrentLanguage'];
|
||||
$flexFormRowData = $this->data['flexFormRowData'];
|
||||
|
||||
$resultArray = $this->initializeResultArray();
|
||||
$resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/Tabs';
|
||||
|
||||
$domIdPrefix = 'DTM-' . GeneralUtility::shortMD5($this->data['parameterArray']['itemFormElName'] . $flexFormCurrentLanguage);
|
||||
$tabCounter = 0;
|
||||
$tabElements = array();
|
||||
foreach ($flexFormDataStructureArray['sheets'] as $sheetName => $sheetDataStructure) {
|
||||
$flexFormRowSheetDataSubPart = $flexFormRowData['data'][$sheetName][$flexFormCurrentLanguage];
|
||||
|
||||
if (!is_array($sheetDataStructure['ROOT']['el'])) {
|
||||
$resultArray['html'] .= LF . 'No Data Structure ERROR: No [\'ROOT\'][\'el\'] found for sheet "' . $sheetName . '".';
|
||||
continue;
|
||||
}
|
||||
|
||||
$tabCounter ++;
|
||||
|
||||
// Assemble key for loading the correct CSH file
|
||||
// @todo: what is that good for? That is for the title of single elements ... see FlexFormElementContainer!
|
||||
$dsPointerFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['ds_pointerField'], true);
|
||||
$parameterArray['_cshKey'] = $table . '.' . $fieldName;
|
||||
foreach ($dsPointerFields as $key) {
|
||||
if ((string)$row[$key] !== '') {
|
||||
$parameterArray['_cshKey'] .= '.' . $row[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$options = $this->data;
|
||||
$options['flexFormDataStructureArray'] = $sheetDataStructure['ROOT']['el'];
|
||||
$options['flexFormRowData'] = $flexFormRowSheetDataSubPart;
|
||||
$options['flexFormFormPrefix'] = '[data][' . $sheetName . '][' . $flexFormCurrentLanguage . ']';
|
||||
$options['parameterArray'] = $parameterArray;
|
||||
// Merge elements of this tab into a single list again and hand over to
|
||||
// palette and single field container to render this group
|
||||
$options['tabAndInlineStack'][] = array(
|
||||
'tab',
|
||||
$domIdPrefix . '-' . $tabCounter,
|
||||
);
|
||||
$options['renderType'] = 'flexFormElementContainer';
|
||||
$childReturn = $this->nodeFactory->create($options)->render();
|
||||
|
||||
$tabElements[] = array(
|
||||
'label' => !empty($sheetDataStructure['ROOT']['sheetTitle']) ? $languageService->sL($sheetDataStructure['ROOT']['sheetTitle']) : $sheetName,
|
||||
'content' => $childReturn['html'],
|
||||
'description' => $sheetDataStructure['ROOT']['sheetDescription'] ? $languageService->sL($sheetDataStructure['ROOT']['sheetDescription']) : '',
|
||||
'linkTitle' => $sheetDataStructure['ROOT']['sheetShortDescr'] ? $languageService->sL($sheetDataStructure['ROOT']['sheetShortDescr']) : '',
|
||||
);
|
||||
|
||||
$childReturn['html'] = '';
|
||||
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childReturn);
|
||||
}
|
||||
|
||||
// Feed everything to document template for tab rendering
|
||||
$resultArray['html'] = $this->renderTabMenu($tabElements, $domIdPrefix);
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService()
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,707 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Form\FormDataProvider;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Form\FormDataCompiler;
|
||||
use TYPO3\CMS\Backend\Form\FormDataGroup\FlexFormSegment;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProvider\AbstractItemProvider;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
|
||||
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Process data structures and data values, calculate defaults.
|
||||
*
|
||||
* This is typically the last provider, executed after TcaFlexPrepare
|
||||
*/
|
||||
class TcaFlexProcess implements FormDataProviderInterface
|
||||
{
|
||||
/**
|
||||
* Determine possible pageTsConfig overrides and apply them to ds.
|
||||
* Determine available languages and sanitize dv for further processing. Then kick
|
||||
* and validate further details like excluded fields. Finally for each possible
|
||||
* value and ds call FormDataCompiler with set FlexFormSegment group to resolve
|
||||
* single field stuff like item processor functions.
|
||||
*
|
||||
* @param array $result
|
||||
* @return array
|
||||
*/
|
||||
public function addData(array $result)
|
||||
{
|
||||
foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
|
||||
if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'flex') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$flexIdentifier = $this->getFlexIdentifier($result, $fieldName);
|
||||
$pageTsConfigOfFlex = $this->getPageTsOfFlex($result, $fieldName, $flexIdentifier);
|
||||
$result = $this->modifyOuterDataStructure($result, $fieldName, $pageTsConfigOfFlex);
|
||||
$result = $this->removeExcludeFieldsFromDataStructure($result, $fieldName, $flexIdentifier);
|
||||
$result = $this->removeDisabledFieldsFromDataStructure($result, $fieldName, $pageTsConfigOfFlex);
|
||||
$result = $this->prepareLanguageHandlingInDataValues($result, $fieldName);
|
||||
$result = $this->modifyDataStructureAndDataValuesByFlexFormSegmentGroup($result, $fieldName, $pageTsConfigOfFlex);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take care of ds_pointerField and friends to determine the correct sub array within
|
||||
* TCA config ds.
|
||||
*
|
||||
* Gets extension identifier. Use second pointer field if it's value is not empty, "list" or "*",
|
||||
* else it must be a plugin and first one will be used.
|
||||
* This code basically determines the sub key of ds field:
|
||||
* config = array(
|
||||
* ds => array(
|
||||
* 'aFlexConfig' => '<flexXml ...
|
||||
* ^^^^^^^^^^^
|
||||
* $flexformIdentifier contains "aFlexConfig" after this operation.
|
||||
*
|
||||
* @todo: This method is only implemented half. It basically should do all the
|
||||
* @todo: pointer handling that is done within BackendUtility::getFlexFormDS() to $srcPointer.
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @return string Pointer
|
||||
*/
|
||||
protected function getFlexIdentifier(array $result, $fieldName)
|
||||
{
|
||||
// @todo: Current implementation with the "list_type, CType" fallback is rather limited and customized for
|
||||
// @todo: tt_content, also it forces a ds_pointerField to be defined and a casual "default" sub array does not work
|
||||
$pointerFields = !empty($result['processedTca']['columns'][$fieldName]['config']['ds_pointerField'])
|
||||
? $result['processedTca']['columns'][$fieldName]['config']['ds_pointerField']
|
||||
: 'list_type,CType';
|
||||
$pointerFields = GeneralUtility::trimExplode(',', $pointerFields);
|
||||
$flexformIdentifier = !empty($result['databaseRow'][$pointerFields[0]]) ? $result['databaseRow'][$pointerFields[0]] : '';
|
||||
if (!empty($result['databaseRow'][$pointerFields[1]])
|
||||
&& $result['databaseRow'][$pointerFields[1]] !== 'list'
|
||||
&& $result['databaseRow'][$pointerFields[1]] !== '*'
|
||||
) {
|
||||
$flexformIdentifier = $result['databaseRow'][$pointerFields[1]];
|
||||
}
|
||||
if (empty($flexformIdentifier)) {
|
||||
$flexformIdentifier = 'default';
|
||||
}
|
||||
|
||||
return $flexformIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine TCEFORM.aTable.aField.matchingIdentifier
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Handled field name
|
||||
* @param string $flexIdentifier Determined identifier
|
||||
* @return array PageTsConfig for this flex
|
||||
*/
|
||||
protected function getPageTsOfFlex(array $result, $fieldName, $flexIdentifier)
|
||||
{
|
||||
$table = $result['tableName'];
|
||||
$pageTs = [];
|
||||
if (!empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'])
|
||||
&& is_array($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'])) {
|
||||
$pageTs = $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.'][$flexIdentifier . '.'];
|
||||
}
|
||||
return $pageTs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "outer" flex data structure changes like language and sheet
|
||||
* description. Does not change "TCA" or values of single elements
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @param array $pageTsConfig Given pageTsConfig of this flex form
|
||||
* @return array Modified item array
|
||||
*/
|
||||
protected function modifyOuterDataStructure(array $result, $fieldName, $pageTsConfig)
|
||||
{
|
||||
$modifiedDataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
|
||||
|
||||
if (isset($pageTsConfig['langDisable'])) {
|
||||
$modifiedDataStructure['meta']['langDisable'] = $pageTsConfig['langDisable'];
|
||||
}
|
||||
if (isset($pageTsConfig['langChildren'])) {
|
||||
$modifiedDataStructure['meta']['langChildren'] = $pageTsConfig['langChildren'];
|
||||
}
|
||||
|
||||
if (isset($modifiedDataStructure['sheets']) && is_array($modifiedDataStructure['sheets'])) {
|
||||
// Handling multiple sheets
|
||||
foreach ($modifiedDataStructure['sheets'] as $sheetName => $sheetStructure) {
|
||||
if (isset($pageTsConfig[$sheetName . '.']) && is_array($pageTsConfig[$sheetName . '.'])) {
|
||||
$pageTsOfSheet = $pageTsConfig[$sheetName . '.'];
|
||||
|
||||
// Remove whole sheet if disabled
|
||||
if (!empty($pageTsOfSheet['disabled'])) {
|
||||
unset($modifiedDataStructure['sheets'][$sheetName]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// sheetTitle, sheetDescription, sheetShortDescr
|
||||
$modifiedDataStructure['sheets'][$sheetName] = $this->modifySingleSheetInformation($sheetStructure, $pageTsOfSheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$modifiedDataStructure['meta']['langDisable'] = isset($modifiedDataStructure['meta']['langDisable'])
|
||||
? (bool)$modifiedDataStructure['meta']['langDisable']
|
||||
: false;
|
||||
$modifiedDataStructure['meta']['langChildren'] = isset($modifiedDataStructure['meta']['langChildren'])
|
||||
? (bool)$modifiedDataStructure['meta']['langChildren']
|
||||
: false;
|
||||
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds'] = $modifiedDataStructure;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes fields from data structure the user has no access to
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @param string $flexIdentifier Determined identifier
|
||||
* @return array Modified result
|
||||
*/
|
||||
protected function removeExcludeFieldsFromDataStructure(array $result, $fieldName, $flexIdentifier)
|
||||
{
|
||||
$dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
|
||||
$backendUser = $this->getBackendUser();
|
||||
if ($backendUser->isAdmin() || !isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$userNonExcludeFields = GeneralUtility::trimExplode(',', $backendUser->groupData['non_exclude_fields']);
|
||||
$excludeFieldsPrefix = $result['tableName'] . ':' . $fieldName . ';' . $flexIdentifier . ';';
|
||||
$nonExcludeFields = [];
|
||||
foreach ($userNonExcludeFields as $userNonExcludeField) {
|
||||
if (strpos($userNonExcludeField, $excludeFieldsPrefix) !== false) {
|
||||
$exploded = explode(';', $userNonExcludeField);
|
||||
$sheetName = $exploded[2];
|
||||
$fieldName = $exploded[3];
|
||||
$nonExcludeFields[$sheetName] = $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($dataStructure['sheets'] as $sheetName => $sheetDefinition) {
|
||||
if (!isset($sheetDefinition['ROOT']['el']) || !is_array($sheetDefinition['ROOT']['el'])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($sheetDefinition['ROOT']['el'] as $flexFieldName => $fieldDefinition) {
|
||||
if (!empty($fieldDefinition['exclude']) && empty($nonExcludeFields[$sheetName])) {
|
||||
unset($result['processedTca']['columns'][$fieldName]['config']['ds']['sheets'][$sheetName]['ROOT']['el'][$flexFieldName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "outer" flex data structure changes like language and sheet
|
||||
* description. Does not change "TCA" or values of single elements
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @param array $pageTsConfig Given pageTsConfig of this flex form
|
||||
* @return array Modified item array
|
||||
*/
|
||||
protected function removeDisabledFieldsFromDataStructure(array $result, $fieldName, $pageTsConfig)
|
||||
{
|
||||
$dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
|
||||
if (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
|
||||
return $result;
|
||||
}
|
||||
foreach ($dataStructure['sheets'] as $sheetName => $sheetDefinition) {
|
||||
if (!isset($sheetDefinition['ROOT']['el']) || !is_array($sheetDefinition['ROOT']['el'])
|
||||
|| !isset($pageTsConfig[$sheetName . '.'])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($sheetDefinition['ROOT']['el'] as $flexFieldName => $fieldDefinition) {
|
||||
if (!empty($pageTsConfig[$sheetName . '.'][$flexFieldName . '.']['disabled'])) {
|
||||
unset($result['processedTca']['columns'][$fieldName]['config']['ds']['sheets'][$sheetName]['ROOT']['el'][$flexFieldName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove data values in languages the user has no access to and add dummy entries
|
||||
* for languages that are available but do not exist in data values yet.
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @return array Modified item array
|
||||
*/
|
||||
protected function prepareLanguageHandlingInDataValues(array $result, $fieldName)
|
||||
{
|
||||
$backendUser = $this->getBackendUser();
|
||||
$dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
|
||||
|
||||
$langDisabled = $dataStructure['meta']['langDisable'];
|
||||
$langChildren = $dataStructure['meta']['langChildren'];
|
||||
|
||||
// Existing page language overlays are only considered if options.checkPageLanguageOverlay is set in userTs
|
||||
$checkPageLanguageOverlay = false;
|
||||
if (isset($result['userTsConfig']['options.']) && is_array($result['userTsConfig']['options.'])
|
||||
&& array_key_exists('checkPageLanguageOverlay', $result['userTsConfig']['options.'])
|
||||
) {
|
||||
$checkPageLanguageOverlay = (bool)$result['userTsConfig']['options.']['checkPageLanguageOverlay'];
|
||||
}
|
||||
|
||||
$systemLanguageRows = $result['systemLanguageRows'];
|
||||
|
||||
// Contains all language iso code that are valid and user has access to
|
||||
$availableLanguageCodes = [];
|
||||
$defaultCodeWasAdded = false;
|
||||
foreach ($systemLanguageRows as $systemLanguageRow) {
|
||||
$isoCode = $systemLanguageRow['iso'];
|
||||
$isAvailable = true;
|
||||
if ($langDisabled && $isoCode !== 'DEF') {
|
||||
$isAvailable = false;
|
||||
}
|
||||
// @todo: Is it possible a user has no write access to default lang? If so, what to do?
|
||||
if (!$backendUser->checkLanguageAccess($systemLanguageRow['uid'])) {
|
||||
$isAvailable = false;
|
||||
}
|
||||
if ($checkPageLanguageOverlay && $systemLanguageRow['uid'] > 0) {
|
||||
$found = false;
|
||||
foreach ($result['pageLanguageOverlayRows'] as $overlayRow) {
|
||||
if ((int)$overlayRow['sys_language_uid'] === (int)$systemLanguageRow['uid']) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$isAvailable = false;
|
||||
}
|
||||
}
|
||||
if ($isoCode === 'DEF' && $defaultCodeWasAdded) {
|
||||
$isAvailable = false;
|
||||
}
|
||||
if ($isAvailable) {
|
||||
$availableLanguageCodes[] = $isoCode;
|
||||
}
|
||||
if ($isoCode === 'DEF') {
|
||||
$defaultCodeWasAdded = true;
|
||||
}
|
||||
}
|
||||
// Set the list of available languages in the data structure "meta" section to have it
|
||||
// available for the render engine to iterate over it.
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['availableLanguageCodes'] = $availableLanguageCodes;
|
||||
|
||||
if (!$langChildren) {
|
||||
$allowedLanguageSheetKeys = [];
|
||||
foreach ($availableLanguageCodes as $isoCode) {
|
||||
$allowedLanguageSheetKeys['l' . $isoCode] = [];
|
||||
}
|
||||
$result = $this->setLanguageSheetsInDataValues($result, $fieldName, $allowedLanguageSheetKeys);
|
||||
|
||||
// With $langChildren = 0, values must only contain vDEF prefixed keys
|
||||
$allowedValueLevelLanguageKeys = [];
|
||||
$allowedValueLevelLanguageKeys['vDEF'] = [];
|
||||
$allowedValueLevelLanguageKeys['vDEF.vDEFbase'] = [];
|
||||
// A richtext special
|
||||
$allowedValueLevelLanguageKeys['_TRANSFORM_vDEF.vDEFbase'] = [];
|
||||
$result = $this->setLanguageValueLevelValues($result, $fieldName, $allowedValueLevelLanguageKeys);
|
||||
} else {
|
||||
// langChildren is set - only lDEF as sheet language is allowed, but more fields on value field level
|
||||
$allowedLanguageSheetKeys = [
|
||||
'lDEF' => [],
|
||||
];
|
||||
$result = $this->setLanguageSheetsInDataValues($result, $fieldName, $allowedLanguageSheetKeys);
|
||||
|
||||
$allowedValueLevelLanguageKeys = [];
|
||||
foreach ($availableLanguageCodes as $isoCode) {
|
||||
$allowedValueLevelLanguageKeys['v' . $isoCode] = [];
|
||||
$allowedValueLevelLanguageKeys['v' . $isoCode . '.vDEFbase'] = [];
|
||||
$allowedValueLevelLanguageKeys['_TRANSFORM_v' . $isoCode . '.vDEFbase'] = [];
|
||||
}
|
||||
$result = $this->setLanguageValueLevelValues($result, $fieldName, $allowedValueLevelLanguageKeys);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Feed single flex field and data to FlexFormSegment FormData compiler and merge result.
|
||||
* This one is nasty. Goal is to have processed TCA stuff in DS and also have validated / processed data values.
|
||||
*
|
||||
* Three main parts in this method:
|
||||
* * Process values of existing section container for default values
|
||||
* * Process values and TCA of possible section container and create a default value row for each
|
||||
* * Process TCA of "normal" fields and have default values in data ['templateRows']['containerName'] parallel to section ['el']
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @param array $pageTsConfig Given pageTsConfig of this flex form
|
||||
* @return array Modified item array
|
||||
*/
|
||||
protected function modifyDataStructureAndDataValuesByFlexFormSegmentGroup(array $result, $fieldName, $pageTsConfig)
|
||||
{
|
||||
$dataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
|
||||
$dataValues = $result['databaseRow'][$fieldName];
|
||||
$tableName = $result['tableName'];
|
||||
|
||||
$availableLanguageCodes = $result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['availableLanguageCodes'];
|
||||
if ($dataStructure['meta']['langChildren']) {
|
||||
$languagesOnSheetLevel = [ 'DEF' ];
|
||||
$languagesOnElementLevel = $availableLanguageCodes;
|
||||
} else {
|
||||
$languagesOnSheetLevel = $availableLanguageCodes;
|
||||
$languagesOnElementLevel = [ 'DEF' ];
|
||||
}
|
||||
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['languagesOnSheetLevel'] = $languagesOnSheetLevel;
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds']['meta']['languagesOnElement'] = $languagesOnElementLevel;
|
||||
|
||||
if (!isset($dataStructure['sheets']) || !is_array($dataStructure['sheets'])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** @var FlexFormSegment $formDataGroup */
|
||||
$formDataGroup = GeneralUtility::makeInstance(FlexFormSegment::class);
|
||||
/** @var FormDataCompiler $formDataCompiler */
|
||||
$formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
|
||||
|
||||
foreach ($dataStructure['sheets'] as $dataStructureSheetName => $dataStructureSheetDefinition) {
|
||||
if (!isset($dataStructureSheetDefinition['ROOT']['el']) || !is_array($dataStructureSheetDefinition['ROOT']['el'])) {
|
||||
continue;
|
||||
}
|
||||
$dataStructureSheetElements = $dataStructureSheetDefinition['ROOT']['el'];
|
||||
|
||||
// Prepare pageTsConfig of this sheet
|
||||
$pageTsConfig['TCEFORM.'][$tableName . '.'] = [];
|
||||
if (isset($pageTsConfig[$dataStructureSheetName . '.']) && is_array($pageTsConfig[$dataStructureSheetName . '.'])) {
|
||||
$pageTsConfig['TCEFORM.'][$tableName . '.'] = $pageTsConfig[$dataStructureSheetName . '.'];
|
||||
}
|
||||
|
||||
foreach ($languagesOnSheetLevel as $isoSheetLevel) {
|
||||
$langSheetLevel = 'l' . $isoSheetLevel;
|
||||
foreach ($dataStructureSheetElements as $dataStructureSheetElementName => $dataStructureSheetElementDefinition) {
|
||||
if (isset($dataStructureSheetElementDefinition['type']) && $dataStructureSheetElementDefinition['type'] === 'array'
|
||||
&& isset($dataStructureSheetElementDefinition['section']) && $dataStructureSheetElementDefinition['section'] === '1'
|
||||
) {
|
||||
// A section
|
||||
|
||||
// Existing section container elements
|
||||
if (isset($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'])
|
||||
&& is_array($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'])
|
||||
) {
|
||||
$containerArray = $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el'];
|
||||
foreach ($containerArray as $aContainerNumber => $aContainerArray) {
|
||||
if (is_array($aContainerArray)) {
|
||||
foreach ($aContainerArray as $aContainerName => $aContainerElementArray) {
|
||||
if ($aContainerName === '_TOGGLE') {
|
||||
// Don't handle internal toggle state field
|
||||
continue;
|
||||
}
|
||||
if (!isset($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName])) {
|
||||
// Container not defined in ds
|
||||
continue;
|
||||
}
|
||||
foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'][$aContainerName]['el'] as $singleFieldName => $singleFieldConfiguration) {
|
||||
// $singleFieldValueArray = ['data']['sSections']['lDEF']['section_1']['el']['1']['container_1']['el']['element_1']
|
||||
$singleFieldValueArray = [];
|
||||
if (isset($aContainerElementArray['el'][$singleFieldName])
|
||||
&& is_array($aContainerElementArray['el'][$singleFieldName])
|
||||
) {
|
||||
$singleFieldValueArray = $aContainerElementArray['el'][$singleFieldName];
|
||||
}
|
||||
foreach ($languagesOnElementLevel as $isoElementLevel) {
|
||||
$langElementLevel = 'v' . $isoElementLevel;
|
||||
$valueArray = [
|
||||
'uid' => $result['databaseRow']['uid'],
|
||||
];
|
||||
$command = 'new';
|
||||
if (array_key_exists($langElementLevel, $singleFieldValueArray)) {
|
||||
$command = 'edit';
|
||||
$valueArray[$singleFieldName] = $singleFieldValueArray[$langElementLevel];
|
||||
}
|
||||
$inputToFlexFormSegment = [
|
||||
'tableName' => $result['tableName'],
|
||||
'command' => $command,
|
||||
// It is currently not possible to have pageTsConfig for section container
|
||||
'pageTsConfig' => [],
|
||||
'databaseRow' => $valueArray,
|
||||
'processedTca' => [
|
||||
'ctrl' => [],
|
||||
'columns' => [
|
||||
$singleFieldName => $singleFieldConfiguration,
|
||||
],
|
||||
],
|
||||
];
|
||||
$flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
|
||||
// Set data value result
|
||||
if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
|
||||
$result['databaseRow'][$fieldName]
|
||||
['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['el']
|
||||
[$aContainerNumber][$aContainerName]['el']
|
||||
[$singleFieldName][$langElementLevel]
|
||||
= $flexSegmentResult['databaseRow'][$singleFieldName];
|
||||
}
|
||||
// Set TCA structure result, actually, this call *might* be obsolete since the "dummy"
|
||||
// handling below will set it again.
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds']
|
||||
['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
|
||||
[$aContainerName]['el'][$singleFieldName]
|
||||
= $flexSegmentResult['processedTca']['columns'][$singleFieldName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End of existing data value handling
|
||||
|
||||
// Prepare "fresh" row for every possible container
|
||||
if (isset($dataStructureSheetElements[$dataStructureSheetElementName]['el']) && is_array($dataStructureSheetElements[$dataStructureSheetElementName]['el'])) {
|
||||
foreach ($dataStructureSheetElements[$dataStructureSheetElementName]['el'] as $possibleContainerName => $possibleContainerConfiguration) {
|
||||
if (isset($possibleContainerConfiguration['el']) && is_array($possibleContainerConfiguration['el'])) {
|
||||
// Initialize result data array templateRows
|
||||
$result['databaseRow'][$fieldName]
|
||||
['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['templateRows']
|
||||
[$possibleContainerName]['el']
|
||||
= [];
|
||||
foreach ($possibleContainerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) {
|
||||
foreach ($languagesOnElementLevel as $isoElementLevel) {
|
||||
$langElementLevel = 'v' . $isoElementLevel;
|
||||
$inputToFlexFormSegment = [
|
||||
'tableName' => $result['tableName'],
|
||||
'command' => 'new',
|
||||
'pageTsConfig' => [],
|
||||
'databaseRow' => [
|
||||
'uid' => $result['databaseRow']['uid'],
|
||||
],
|
||||
'processedTca' => [
|
||||
'ctrl' => [],
|
||||
'columns' => [
|
||||
$singleFieldName => $singleFieldConfiguration,
|
||||
],
|
||||
],
|
||||
];
|
||||
$flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
|
||||
if (array_key_exists($singleFieldName, $flexSegmentResult['databaseRow'])) {
|
||||
$result['databaseRow'][$fieldName]
|
||||
['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName]['templateRows']
|
||||
[$possibleContainerName]['el'][$singleFieldName][$langElementLevel]
|
||||
= $flexSegmentResult['databaseRow'][$singleFieldName];
|
||||
}
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds']
|
||||
['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]['el']
|
||||
[$possibleContainerName]['el'][$singleFieldName]
|
||||
= $flexSegmentResult['processedTca']['columns'][$singleFieldName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End of preparation for each possible container
|
||||
|
||||
// type without section is not ok
|
||||
} elseif (isset($dataStructureSheetElementDefinition['type']) || isset($dataStructureSheetElementDefinition['section'])) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Broken data structure on field name ' . $fieldName . '. section without type or vice versa is not allowed',
|
||||
1440685208
|
||||
);
|
||||
|
||||
// A "normal" TCA element
|
||||
} else {
|
||||
foreach ($languagesOnElementLevel as $isoElementLevel) {
|
||||
$langElementLevel = 'v' . $isoElementLevel;
|
||||
$valueArray = [
|
||||
// uid of "parent" is given down for inline elements to resolve correctly
|
||||
'uid' => $result['databaseRow']['uid'],
|
||||
];
|
||||
$command = 'new';
|
||||
if (isset($dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName])
|
||||
&& array_key_exists($langElementLevel, $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName])
|
||||
) {
|
||||
$command = 'edit';
|
||||
$valueArray[$dataStructureSheetElementName] = $dataValues['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName][$langElementLevel];
|
||||
}
|
||||
$inputToFlexFormSegment = [
|
||||
// tablename of "parent" is given down for inline elements to resolve correctly
|
||||
'tableName' => $result['tableName'],
|
||||
'command' => $command,
|
||||
'pageTsConfig' => $pageTsConfig,
|
||||
'databaseRow' => $valueArray,
|
||||
'processedTca' => [
|
||||
'ctrl' => [],
|
||||
'columns' => [
|
||||
$dataStructureSheetElementName => $dataStructureSheetElementDefinition,
|
||||
],
|
||||
],
|
||||
];
|
||||
$flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
|
||||
// Set data value result
|
||||
if (array_key_exists($dataStructureSheetElementName, $flexSegmentResult['databaseRow'])) {
|
||||
$result['databaseRow'][$fieldName]
|
||||
['data'][$dataStructureSheetName][$langSheetLevel][$dataStructureSheetElementName][$langElementLevel]
|
||||
= $flexSegmentResult['databaseRow'][$dataStructureSheetElementName];
|
||||
}
|
||||
// Set TCA structure result
|
||||
$result['processedTca']['columns'][$fieldName]['config']['ds']
|
||||
['sheets'][$dataStructureSheetName]['ROOT']['el'][$dataStructureSheetElementName]
|
||||
= $flexSegmentResult['processedTca']['columns'][$dataStructureSheetElementName];
|
||||
}
|
||||
} // End of single element handling
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify data structure of a single "sheet"
|
||||
* Sets "secondary" data like sheet names and so on, but does NOT modify single elements
|
||||
*
|
||||
* @param array $dataStructure Given data structure
|
||||
* @param array $pageTsOfSheet Page Ts config of given field
|
||||
* @return array Modified data structure
|
||||
*/
|
||||
protected function modifySingleSheetInformation(array $dataStructure, array $pageTsOfSheet)
|
||||
{
|
||||
// Return if no elements defined
|
||||
if (!isset($dataStructure['ROOT']['el']) || !is_array($dataStructure['ROOT']['el'])) {
|
||||
return $dataStructure;
|
||||
}
|
||||
|
||||
// Rename sheet (tab)
|
||||
if (!empty($pageTsOfSheet['sheetTitle'])) {
|
||||
$dataStructure['ROOT']['sheetTitle'] = $pageTsOfSheet['sheetTitle'];
|
||||
}
|
||||
// Set sheet description (tab)
|
||||
if (!empty($pageTsOfSheet['sheetDescription'])) {
|
||||
$dataStructure['ROOT']['sheetDescription'] = $pageTsOfSheet['sheetDescription'];
|
||||
}
|
||||
// Set sheet short description (tab)
|
||||
if (!empty($pageTsOfSheet['sheetShortDescr'])) {
|
||||
$dataStructure['ROOT']['sheetShortDescr'] = $pageTsOfSheet['sheetShortDescr'];
|
||||
}
|
||||
|
||||
return $dataStructure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new sheet languages not yet in data values and remove invalid ones
|
||||
*
|
||||
* databaseRow['aFlex']['data']['sDEF'] = array('lDEF', 'lNotAllowed');
|
||||
* allowedLanguageKeys = array('lDEF', 'lNEW')
|
||||
* -> databaseRow['aFlex']['data']['sDEF'] = array('lDEF', 'lNEW');
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @param array $allowedKeys List of allowed keys
|
||||
* @return array Modified result
|
||||
*/
|
||||
protected function setLanguageSheetsInDataValues(array $result, $fieldName, array $allowedKeys)
|
||||
{
|
||||
$valueArray = [];
|
||||
if (isset($result['databaseRow'][$fieldName]['data']) && is_array($result['databaseRow'][$fieldName]['data'])) {
|
||||
$valueArray = $result['databaseRow'][$fieldName]['data'];
|
||||
}
|
||||
foreach ($valueArray as $sheetName => $sheetLanguages) {
|
||||
// Add iso code with empty array if it does not yet exist in data
|
||||
// and remove codes from data that do not exist in $allowed
|
||||
$result['databaseRow'][$fieldName]['data'][$sheetName]
|
||||
= array_intersect_key(array_merge($allowedKeys, $sheetLanguages), $allowedKeys);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove invalid keys from data value array the user has no access to
|
||||
* or that were removed or similar to prevent any rendering of this stuff
|
||||
*
|
||||
* Handles this for "normal" fields and also for section container element values.
|
||||
*
|
||||
* @param array $result Result array
|
||||
* @param string $fieldName Current handle field name
|
||||
* @param array $allowedKeys List of allowed keys
|
||||
* @return array Modified result
|
||||
*/
|
||||
protected function setLanguageValueLevelValues(array $result, $fieldName, $allowedKeys)
|
||||
{
|
||||
$valueArray = [];
|
||||
if (isset($result['databaseRow'][$fieldName]['data']) && is_array($result['databaseRow'][$fieldName]['data'])) {
|
||||
$valueArray = $result['databaseRow'][$fieldName]['data'];
|
||||
}
|
||||
foreach ($valueArray as $sheetName => $sheetLanguages) {
|
||||
if (!is_array($sheetLanguages)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($sheetLanguages as $languageName => $languageFields) {
|
||||
if (!is_array($languageFields)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($languageFields as $flexFieldName => $fieldValues) {
|
||||
if (!is_array($fieldValues)) {
|
||||
continue;
|
||||
}
|
||||
$allowedSingleValues = [];
|
||||
foreach ($fieldValues as $fieldValueName => $fieldValueValue) {
|
||||
if (is_array($fieldValueValue) && $fieldValueName === 'el') {
|
||||
// A section container
|
||||
foreach ($fieldValueValue as $sectionNumber => $sectionElementArray) {
|
||||
if (is_array($sectionElementArray)) {
|
||||
$allowedSingleValues['el'][$sectionNumber] = [];
|
||||
foreach ($sectionElementArray as $sectionElementName => $containerElementArray) {
|
||||
if (isset($containerElementArray['el']) && is_array($containerElementArray['el']) && !empty($containerElementArray['el'])) {
|
||||
foreach ($containerElementArray['el'] as $aContainerElementName => $aContainerElementValues) {
|
||||
if (is_array($aContainerElementValues)) {
|
||||
foreach ($aContainerElementValues as $aContainerElementValueKey => $aContainerElementValueValue) {
|
||||
if (array_key_exists($aContainerElementValueKey, $allowedKeys)) {
|
||||
$allowedSingleValues['el'][$sectionNumber][$sectionElementName]
|
||||
['el'][$aContainerElementName][$aContainerElementValueKey] = $aContainerElementValueValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$allowedSingleValues['el'][$sectionNumber][$sectionElementName]['el']
|
||||
[$aContainerElementName] = $aContainerElementValues;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$allowedSingleValues['el'][$sectionNumber][$sectionElementName] = $containerElementArray;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$allowedSingleValues = $sectionElementArray;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// "normal" value field
|
||||
if (array_key_exists($fieldValueName, $allowedKeys)) {
|
||||
$allowedSingleValues[$fieldValueName] = $fieldValueValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$result['databaseRow'][$fieldName]['data'][$sheetName][$languageName][$flexFieldName] = $allowedSingleValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUser()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Hooks\ExtTablesPostProcessing;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Database\TableConfigurationPostProcessingHookInterface;
|
||||
use TYPO3\Cms\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Migrate TCA that was added by extensions in ext_tables.php
|
||||
*
|
||||
* This is deprecated, all extensions should register / manipulate TCA in Configuration/TCA nowadays.
|
||||
*/
|
||||
class TcaMigration implements TableConfigurationPostProcessingHookInterface
|
||||
{
|
||||
/**
|
||||
* Run migration dynamically a second time on *every* request.
|
||||
* This can not be cached and is slow.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function processData()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Core\Migrations\TcaMigration $tcaMigration */
|
||||
$tcaMigration = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Migrations\TcaMigration::class);
|
||||
$GLOBALS['TCA'] = $tcaMigration->migrate($GLOBALS['TCA']);
|
||||
$messages = $tcaMigration->getMessages();
|
||||
if (!empty($messages)) {
|
||||
$context = 'ext:compatibility6 did an automatic migration of TCA during bootstrap. This costs performance on every'
|
||||
. ' call. It also means some old extensions register TCA in ext_tables.php and not in Configuration/TCA.'
|
||||
. ' Please adapt TCA accordingly until this message is not thrown anymore and unload extension compatibility6'
|
||||
. ' as soon as possible';
|
||||
array_unshift($messages, $context);
|
||||
GeneralUtility::deprecationLog(implode(LF, $messages));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Hooks\PageLayoutView;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains a preview rendering for the page module of
|
||||
* CType="mailform"
|
||||
*/
|
||||
class MailformPreviewRenderer implements \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface
|
||||
{
|
||||
/**
|
||||
* Preprocesses the preview rendering of a content element of type "mailform"
|
||||
*
|
||||
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
|
||||
* @param bool $drawItem Whether to draw the item using the default functionality
|
||||
* @param string $headerContent Header content
|
||||
* @param string $itemContent Item content
|
||||
* @param array $row Record row of tt_content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function preProcess(\TYPO3\CMS\Backend\View\PageLayoutView &$parentObject, &$drawItem, &$headerContent, &$itemContent, array &$row)
|
||||
{
|
||||
if ($row['CType'] === 'mailform') {
|
||||
$itemContent = $parentObject->linkEditContent($parentObject->renderText($row['bodytext']), $row) . '<br />';
|
||||
$drawItem = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Hooks\PageLayoutView;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
|
||||
use TYPO3\CMS\Lang\LanguageService;
|
||||
use TYPO3\CMS\Backend\View\PageLayoutView;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
|
||||
/**
|
||||
* Contains a preview rendering for the page module of CType="script"
|
||||
*/
|
||||
class ScriptPreviewRenderer implements PageLayoutViewDrawItemHookInterface
|
||||
{
|
||||
/**
|
||||
* Preprocesses the preview rendering of a content element of type "script"
|
||||
*
|
||||
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
|
||||
* @param bool $drawItem Whether to draw the item using the default functionality
|
||||
* @param string $headerContent Header content
|
||||
* @param string $itemContent Item content
|
||||
* @param array $row Record row of tt_content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function preProcess(
|
||||
PageLayoutView &$parentObject,
|
||||
&$drawItem,
|
||||
&$headerContent,
|
||||
&$itemContent,
|
||||
array &$row
|
||||
) {
|
||||
if ($row['CType'] === 'script') {
|
||||
$itemContent .= $this->getLanguageService()->sL(
|
||||
BackendUtility::getItemLabel('tt_content', 'select_key'),
|
||||
true
|
||||
) . ' ' . $row['select_key'] . '<br />';
|
||||
$itemContent .= '<br />' . $parentObject->linkEditContent(
|
||||
$parentObject->renderText($row['bodytext']),
|
||||
$row
|
||||
) . '<br />';
|
||||
$itemContent .= '<br />' . $parentObject->linkEditContent(
|
||||
$parentObject->renderText($row['imagecaption']),
|
||||
$row
|
||||
) . '<br />';
|
||||
|
||||
$drawItem = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language service
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService()
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Hooks\TypoScriptFrontendController;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Html\HtmlParser;
|
||||
|
||||
/**
|
||||
* Class that hooks into TypoScriptFrontendController to do XHTML cleaning and prefixLocalAnchors functionality
|
||||
*/
|
||||
class ContentPostProcHook
|
||||
{
|
||||
/**
|
||||
* @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
|
||||
*/
|
||||
protected $pObj;
|
||||
|
||||
/**
|
||||
* XHTML-clean the code, if flag config.xhtml_cleaning is set
|
||||
* to "all", same goes for config.prefixLocalAnchors
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $parentObject
|
||||
*/
|
||||
public function contentPostProcAll(&$parameters, $parentObject)
|
||||
{
|
||||
$this->pObj = $parentObject;
|
||||
// Fix local anchors in links, if flag set
|
||||
if ($this->doLocalAnchorFix() === 'all') {
|
||||
$GLOBALS['TT']->push('Local anchor fix, all', '');
|
||||
$this->prefixLocalAnchorsWithScript();
|
||||
$GLOBALS['TT']->pull();
|
||||
}
|
||||
// XHTML-clean the code, if flag set
|
||||
if ($this->doXHTML_cleaning() === 'all') {
|
||||
$GLOBALS['TT']->push('XHTML clean, all', '');
|
||||
$XHTML_clean = GeneralUtility::makeInstance(HtmlParser::class);
|
||||
$this->pObj->content = $XHTML_clean->XHTML_clean($this->pObj->content);
|
||||
$GLOBALS['TT']->pull();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XHTML-clean the code, if flag config.xhtml_cleaning is set
|
||||
* to "cached", same goes for config.prefixLocalAnchors
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $parentObject
|
||||
*/
|
||||
public function contentPostProcCached(&$parameters, $parentObject)
|
||||
{
|
||||
$this->pObj = $parentObject;
|
||||
// Fix local anchors in links, if flag set
|
||||
if ($this->doLocalAnchorFix() === 'cached') {
|
||||
$GLOBALS['TT']->push('Local anchor fix, cached', '');
|
||||
$this->prefixLocalAnchorsWithScript();
|
||||
$GLOBALS['TT']->pull();
|
||||
}
|
||||
// XHTML-clean the code, if flag set
|
||||
if ($this->doXHTML_cleaning() === 'cached') {
|
||||
$GLOBALS['TT']->push('XHTML clean, cached', '');
|
||||
$XHTML_clean = GeneralUtility::makeInstance(HtmlParser::class);
|
||||
$this->pObj->content = $XHTML_clean->XHTML_clean($this->pObj->content);
|
||||
$GLOBALS['TT']->pull();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* XHTML-clean the code, if flag config.xhtml_cleaning is set
|
||||
* to "output", same goes for config.prefixLocalAnchors
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $parentObject
|
||||
*/
|
||||
public function contentPostProcOutput(&$parameters, $parentObject)
|
||||
{
|
||||
$this->pObj = $parentObject;
|
||||
// Fix local anchors in links, if flag set
|
||||
if ($this->doLocalAnchorFix() === 'output') {
|
||||
$GLOBALS['TT']->push('Local anchor fix, output', '');
|
||||
$this->prefixLocalAnchorsWithScript();
|
||||
$GLOBALS['TT']->pull();
|
||||
}
|
||||
// XHTML-clean the code, if flag set
|
||||
if ($this->doXHTML_cleaning() === 'output') {
|
||||
$GLOBALS['TT']->push('XHTML clean, output', '');
|
||||
$XHTML_clean = GeneralUtility::makeInstance(HtmlParser::class);
|
||||
$this->pObj->content = $XHTML_clean->XHTML_clean($this->pObj->content);
|
||||
$GLOBALS['TT']->pull();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mode of XHTML cleaning
|
||||
*
|
||||
* @return string Keyword: "all", "cached", "none" or "output"
|
||||
*/
|
||||
protected function doXHTML_cleaning()
|
||||
{
|
||||
if ($this->pObj->config['config']['xmlprologue'] === 'none') {
|
||||
return 'none';
|
||||
}
|
||||
return $this->pObj->config['config']['xhtml_cleaning'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the mode of Local Anchor prefixing
|
||||
*
|
||||
* @return string Keyword: "all", "cached" or "output"
|
||||
*/
|
||||
public function doLocalAnchorFix()
|
||||
{
|
||||
return isset($this->pObj->config['config']['prefixLocalAnchors']) ? $this->pObj->config['config']['prefixLocalAnchors'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes all occurrences of <a href="#"... in $this->content with <a href="[path-to-url]#"...
|
||||
*
|
||||
* @return void Works directly on $this->content
|
||||
*/
|
||||
protected function prefixLocalAnchorsWithScript()
|
||||
{
|
||||
if (!$this->pObj->beUserLogin) {
|
||||
if (!is_object($this->pObj->cObj)) {
|
||||
$this->pObj->newCObj();
|
||||
}
|
||||
$scriptPath = $this->pObj->cObj->getUrlToCurrentLocation();
|
||||
} else {
|
||||
// To break less existing sites, we allow the REQUEST_URI to be used for the prefix
|
||||
$scriptPath = GeneralUtility::getIndpEnv('REQUEST_URI');
|
||||
// Disable the cache so that these URI will not be the ones to be cached
|
||||
$this->pObj->no_cache = true;
|
||||
}
|
||||
$originalContent = $this->pObj->content;
|
||||
$this->pObj->content = preg_replace('/(<(?:a|area).*?href=")(#[^"]*")/i', '${1}' . htmlspecialchars($scriptPath) . '${2}', $originalContent);
|
||||
// There was an error in the call to preg_replace, so keep the original content (behavior prior to PHP 5.2)
|
||||
if (preg_last_error() > 0) {
|
||||
GeneralUtility::sysLog('preg_replace returned error-code: ' . preg_last_error() . ' in function prefixLocalAnchorsWithScript. Replacement not done!', 'cms', GeneralUtility::SYSLOG_SEVERITY_FATAL);
|
||||
$this->pObj->content = $originalContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Template;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Extension class for "template" - used in the context of frontend editing.
|
||||
*/
|
||||
class FrontendDocumentTemplate extends \TYPO3\CMS\Backend\Template\DocumentTemplate
|
||||
{
|
||||
/**
|
||||
* Gets instance of PageRenderer
|
||||
*
|
||||
* @return PageRenderer
|
||||
* @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
|
||||
*/
|
||||
public function getPageRenderer()
|
||||
{
|
||||
GeneralUtility::logDeprecatedFunction();
|
||||
if (!isset($this->pageRenderer)) {
|
||||
$this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
|
||||
}
|
||||
return $this->pageRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used in the frontend context to insert header data via TSFE->additionalHeaderData.
|
||||
* Mimics header inclusion from template->startPage().
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function insertHeaderData()
|
||||
{
|
||||
$this->backPath = ($GLOBALS['TSFE']->backPath = TYPO3_mainDir);
|
||||
$this->pageRenderer->setBackPath($this->backPath);
|
||||
$this->docStyle();
|
||||
// Add applied JS/CSS to $GLOBALS['TSFE']
|
||||
if ($this->JScode) {
|
||||
$this->pageRenderer->addHeaderData($this->JScode);
|
||||
}
|
||||
if (!empty($this->JScodeArray)) {
|
||||
foreach ($this->JScodeArray as $name => $code) {
|
||||
$this->pageRenderer->addJsInlineCode($name, $code, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
typo3conf/ext/compatibility6/Classes/Utility/FormUtility.php
Normal file
78
typo3conf/ext/compatibility6/Classes/Utility/FormUtility.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
namespace TYPO3\CMS\Compatibility6\Utility;
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains some functions that were been previously found
|
||||
* inside TypoScriptFrontendController
|
||||
* but are shared between FormContentObject and TypoScriptFrontendController
|
||||
*
|
||||
*/
|
||||
class FormUtility
|
||||
{
|
||||
/**
|
||||
* En/decodes strings with lightweight encryption and a hash containing the server encryptionKey (salt)
|
||||
* Can be used for authentication of information sent from server generated pages back to the server to establish that the server generated the page. (Like hidden fields with recipient mail addresses)
|
||||
* Encryption is mainly to avoid spam-bots to pick up information.
|
||||
*
|
||||
* @param string $string Input string to en/decode
|
||||
* @param bool $decode If set, string is decoded, not encoded.
|
||||
* @return string encoded/decoded version of $string
|
||||
*/
|
||||
public static function codeString($string, $decode = false)
|
||||
{
|
||||
if ($decode) {
|
||||
list($md5Hash, $str) = explode(':', $string, 2);
|
||||
$newHash = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . ':' . $str), 0, 10);
|
||||
if ($md5Hash === $newHash) {
|
||||
$str = base64_decode($str);
|
||||
$str = self::roundTripCryptString($str);
|
||||
return $str;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$str = $string;
|
||||
$str = self::roundTripCryptString($str);
|
||||
$str = base64_encode($str);
|
||||
$newHash = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . ':' . $str), 0, 10);
|
||||
return $newHash . ':' . $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a strings by XOR'ing all characters with a key derived from the
|
||||
* TYPO3 encryption key.
|
||||
*
|
||||
* Using XOR means that the string can be decrypted by simply calling the
|
||||
* function again - just like rot-13 works (but in this case for ANY byte
|
||||
* value).
|
||||
*
|
||||
* @param string $string String to crypt, may be empty
|
||||
* @return string binary crypt string, will have the same length as $string
|
||||
*/
|
||||
protected static function roundTripCryptString($string)
|
||||
{
|
||||
$out = '';
|
||||
$cleartextLength = strlen($string);
|
||||
$key = sha1($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
|
||||
$keyLength = strlen($key);
|
||||
for ($a = 0; $a < $cleartextLength; $a++) {
|
||||
$xorVal = ord($key[$a % $keyLength]);
|
||||
$out .= chr(ord($string[$a]) ^ $xorVal);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* Definitions of routes
|
||||
*/
|
||||
return [
|
||||
// Register wizard
|
||||
'wizard_forms' => [
|
||||
'path' => '/wizard/forms',
|
||||
'target' => \TYPO3\CMS\Compatibility6\Controller\Wizard\FormsController::class . '::mainAction'
|
||||
]
|
||||
];
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or die();
|
||||
|
||||
// Add "pages.storage_pid" field to TCA column
|
||||
$additionalColumns = array(
|
||||
'storage_pid' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:storage_pid',
|
||||
'config' => array(
|
||||
'type' => 'group',
|
||||
'internal_type' => 'db',
|
||||
'allowed' => 'pages',
|
||||
'size' => '1',
|
||||
'maxitems' => '1',
|
||||
'minitems' => '0',
|
||||
'show_thumbs' => '1',
|
||||
'wizards' => array(
|
||||
'suggest' => array(
|
||||
'type' => 'suggest'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages', $additionalColumns);
|
||||
|
||||
// Add palette
|
||||
$GLOBALS['TCA']['pages']['palettes']['storage'] = array(
|
||||
'showitem' => 'storage_pid;LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:pages.storage_pid_formlabel',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
// Add to "normal" pages, "external URL", "shortcut page" and "storage PID"
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('pages',
|
||||
'--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:pages.palettes.storage;storage',
|
||||
\TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_DEFAULT . ','
|
||||
. \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_LINK . ','
|
||||
. \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_SHORTCUT . ','
|
||||
. \TYPO3\CMS\Frontend\Page\PageRepository::DOKTYPE_SYSFOLDER,
|
||||
'after:media'
|
||||
);
|
||||
@@ -0,0 +1,401 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or die();
|
||||
|
||||
//Extra fields for the tt_content table
|
||||
$extraContentColumns = array(
|
||||
'altText' => array(
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_altText',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '3'
|
||||
)
|
||||
),
|
||||
'imagecaption' => array(
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:LGL.caption',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '3',
|
||||
'softref' => 'typolink_tag,images,email[subst],url'
|
||||
)
|
||||
),
|
||||
'imagecaption_position' => array(
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:imagecaption_position',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'items' => array(
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:LGL.default_value',
|
||||
''
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:imagecaption_position.I.1',
|
||||
'center'
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:imagecaption_position.I.2',
|
||||
'right'
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:imagecaption_position.I.3',
|
||||
'left'
|
||||
)
|
||||
),
|
||||
'default' => ''
|
||||
)
|
||||
),
|
||||
'image_link' => array(
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_link',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '3',
|
||||
'wizards' => array(
|
||||
'link' => array(
|
||||
'type' => 'popup',
|
||||
'title' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_link_formlabel',
|
||||
'icon' => 'EXT:compatibility6/Resources/Public/Images/wizard_link.gif',
|
||||
'module' => array(
|
||||
'name' => 'wizard_link',
|
||||
),
|
||||
'JSopenParams' => 'width=800,height=600,status=0,menubar=0,scrollbars=1'
|
||||
)
|
||||
),
|
||||
'softref' => 'typolink[linkList]'
|
||||
)
|
||||
),
|
||||
'image_frames' => array(
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'items' => array(
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.0',
|
||||
0
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.1',
|
||||
1
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.2',
|
||||
2
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.3',
|
||||
3
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.4',
|
||||
4
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.5',
|
||||
5
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.6',
|
||||
6
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.7',
|
||||
7
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames.I.8',
|
||||
8
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
'longdescURL' => array(
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_longdescURL',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '3',
|
||||
'wizards' => array(
|
||||
'link' => array(
|
||||
'type' => 'popup',
|
||||
'title' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_link_formlabel',
|
||||
'icon' => 'EXT:compatibility6/Resources/Public/Images/wizard_link.gif',
|
||||
'module' => array(
|
||||
'name' => 'wizard_link',
|
||||
),
|
||||
'params' => array(
|
||||
'blindLinkOptions' => 'folder,file,mail,spec',
|
||||
'blindLinkFields' => 'target,title,class,params'
|
||||
),
|
||||
'JSopenParams' => 'width=800,height=600,status=0,menubar=0,scrollbars=1'
|
||||
)
|
||||
),
|
||||
'softref' => 'typolink[linkList]'
|
||||
)
|
||||
),
|
||||
'titleText' => array(
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_titleText',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '3'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Adding fields to the tt_content table definition in TCA
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', $extraContentColumns);
|
||||
|
||||
// Add default palettes
|
||||
$GLOBALS['TCA']['tt_content']['palettes'] = array_replace(
|
||||
$GLOBALS['TCA']['tt_content']['palettes'],
|
||||
array(
|
||||
'1' => array(
|
||||
'showitem' => '
|
||||
starttime,
|
||||
endtime
|
||||
'
|
||||
),
|
||||
'2' => array(
|
||||
'showitem' => '
|
||||
imagecols,
|
||||
image_noRows,
|
||||
imageborder
|
||||
'
|
||||
),
|
||||
'3' => array(
|
||||
'showitem' => '
|
||||
header_position,
|
||||
header_layout,
|
||||
header_link,
|
||||
date
|
||||
'
|
||||
),
|
||||
'4' => array(
|
||||
'showitem' => '
|
||||
sys_language_uid,
|
||||
l18n_parent,
|
||||
colPos,
|
||||
spaceBefore,
|
||||
spaceAfter,
|
||||
section_frame,
|
||||
sectionIndex
|
||||
'
|
||||
),
|
||||
'5' => array(
|
||||
'showitem' => '
|
||||
imagecaption_position
|
||||
'
|
||||
),
|
||||
'6' => array(
|
||||
'showitem' => '
|
||||
imagewidth,
|
||||
image_link
|
||||
'
|
||||
),
|
||||
'7' => array(
|
||||
'showitem' => '
|
||||
image_link,
|
||||
image_zoom
|
||||
',
|
||||
),
|
||||
'8' => array(
|
||||
'showitem' => '
|
||||
layout
|
||||
'
|
||||
),
|
||||
'10' => array(
|
||||
'showitem' => '
|
||||
table_bgColor,
|
||||
table_border,
|
||||
table_cellspacing,
|
||||
table_cellpadding
|
||||
'
|
||||
),
|
||||
'11' => array(
|
||||
'showitem' => '
|
||||
image_compression,
|
||||
image_effects,
|
||||
image_frames
|
||||
',
|
||||
),
|
||||
'12' => array(
|
||||
'showitem' => '
|
||||
recursive
|
||||
'
|
||||
),
|
||||
'13' => array(
|
||||
'showitem' => '
|
||||
imagewidth,
|
||||
imageheight
|
||||
',
|
||||
),
|
||||
'14' => array(
|
||||
'showitem' => '
|
||||
sys_language_uid,
|
||||
l18n_parent,
|
||||
colPos
|
||||
'
|
||||
),
|
||||
'image_accessibility' => array(
|
||||
'showitem' => '
|
||||
altText;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:altText_formlabel,
|
||||
titleText;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:titleText_formlabel,
|
||||
--linebreak--,
|
||||
longdescURL;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:longdescURL_formlabel
|
||||
',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Add palettes from css_styled_content if css_styled_content is NOT loaded but needed for CE's "search" and "mailform"
|
||||
if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('css_styled_content')) {
|
||||
$GLOBALS['TCA']['tt_content']['palettes'] = array_replace(
|
||||
$GLOBALS['TCA']['tt_content']['palettes'],
|
||||
array(
|
||||
'visibility' => array(
|
||||
'showitem' => '
|
||||
hidden;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:hidden_formlabel,
|
||||
sectionIndex;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:sectionIndex_formlabel,
|
||||
linkToTop;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:linkToTop_formlabel
|
||||
',
|
||||
),
|
||||
'frames' => array(
|
||||
'showitem' => '
|
||||
layout;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:layout_formlabel,
|
||||
spaceBefore;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:spaceBefore_formlabel,
|
||||
spaceAfter;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:spaceAfter_formlabel,
|
||||
section_frame;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:section_frame_formlabel
|
||||
',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette('tt_content', 'image_settings', 'image_frames;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:image_frames_formlabel');
|
||||
|
||||
/**
|
||||
* CType "search"
|
||||
*/
|
||||
$GLOBALS['TCA']['tt_content']['ctrl']['typeicon_classes']['search'] = 'mimetypes-x-content-form-search';
|
||||
$GLOBALS['TCA']['tt_content']['types']['search'] = array(
|
||||
'showitem' => '--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.general;general,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.header;header,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.frames;frames,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.access,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.visibility;visibility,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.access;access,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.behaviour,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.searchform;searchform,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.extended'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['palettes']['searchform'] = array(
|
||||
'showitem' => 'pages;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:pages.ALT.searchform',
|
||||
);
|
||||
|
||||
// check if there is already a forms tab and add the item after that, otherwise
|
||||
// add the tab item as well
|
||||
$additionalCTypeItem = array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:CType.I.9',
|
||||
'search',
|
||||
'content-special-indexed_search'
|
||||
);
|
||||
|
||||
$existingCTypeItems = $GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'];
|
||||
$groupFound = false;
|
||||
$groupPosition = false;
|
||||
foreach ($existingCTypeItems as $position => $item) {
|
||||
if ($item[0] === 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:CType.div.forms') {
|
||||
$groupFound = true;
|
||||
$groupPosition = $position;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($groupFound && $groupPosition) {
|
||||
// add the new CType item below CType
|
||||
array_splice($GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'], $groupPosition+1, 0, array(0 => $additionalCTypeItem));
|
||||
} else {
|
||||
// nothing found, add two items (group + new CType) at the bottom of the list
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem('tt_content', 'CType',
|
||||
array('LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:CType.div.forms', '--div--')
|
||||
);
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem('tt_content', 'CType', $additionalCTypeItem);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CType "mailform"
|
||||
*/
|
||||
if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('form')) {
|
||||
$GLOBALS['TCA']['tt_content']['ctrl']['typeicon_classes']['mailform'] = 'mimetypes-x-content-form';
|
||||
$GLOBALS['TCA']['tt_content']['columns']['bodytext']['config']['wizards']['forms'] = array(
|
||||
'notNewRecords' => 1,
|
||||
'enableByTypeConfig' => 1,
|
||||
'type' => 'script',
|
||||
'title' => 'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:bodytext.W.forms',
|
||||
'icon' => 'EXT:compatibility6/Resources/Public/Images/wizard_forms.gif',
|
||||
'module' => array(
|
||||
'name' => 'wizard_forms',
|
||||
'urlParameters' => array(
|
||||
'special' => 'formtype_mail'
|
||||
)
|
||||
),
|
||||
'params' => array(
|
||||
'xmlOutput' => 0
|
||||
)
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
|
||||
'tt_content',
|
||||
'CType',
|
||||
array(
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:CType.I.8',
|
||||
'mailform',
|
||||
'content-elements-mailform'
|
||||
),
|
||||
'search',
|
||||
'before'
|
||||
);
|
||||
|
||||
// set up the fields
|
||||
$GLOBALS['TCA']['tt_content']['types']['mailform'] = array(
|
||||
'showitem' => '
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.general;general,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.header;header,
|
||||
bodytext;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:bodytext.ALT.mailform_formlabel,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.frames;frames,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.access,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.visibility;visibility,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.access;access,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.behaviour,
|
||||
--palette--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:palette.mailform;mailform,
|
||||
--div--;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:tabs.extended'
|
||||
);
|
||||
$baseDefaultExtrasOfBodytext = '';
|
||||
if (!empty($GLOBALS['TCA']['tt_content']['columns']['bodytext']['defaultExtras'])) {
|
||||
$baseDefaultExtrasOfBodytext = $GLOBALS['TCA']['tt_content']['columns']['bodytext']['defaultExtras'] . ':';
|
||||
}
|
||||
if (!is_array($GLOBALS['TCA']['tt_content']['types']['mailform']['columnsOverrides'])) {
|
||||
$GLOBALS['TCA']['tt_content']['types']['mailform']['columnsOverrides'] = array();
|
||||
}
|
||||
if (!is_array($GLOBALS['TCA']['tt_content']['types']['mailform']['columnsOverrides']['bodytext'])) {
|
||||
$GLOBALS['TCA']['tt_content']['types']['mailform']['columnsOverrides']['bodytext'] = array();
|
||||
}
|
||||
$GLOBALS['TCA']['tt_content']['types']['mailform']['columnsOverrides']['bodytext']['defaultExtras'] = $baseDefaultExtrasOfBodytext . 'nowrap:wizards[forms]';
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['palettes']['mailform'] = array(
|
||||
'showitem' => 'pages;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:pages.ALT.mailform, --linebreak--, subheader;LLL:EXT:compatibility6/Resources/Private/Language/locallang_ttc.xlf:subheader.ALT.mailform_formlabel',
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
styles.content.mailform {
|
||||
target = {$PAGE_TARGET}
|
||||
# cat=content/cMailform; type=; label= Message, Formmail OK: This is the message (if any) that is popped-up (JavaScript) when a user clicks "send" with an email-form
|
||||
goodMess =
|
||||
# cat=content/cMailform; type=; label= Message, Formmail Missing: This is the message that is popped-up when a user has NOT filled required fields in an email-form
|
||||
badMess =
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
# Hide subheader for old style form element (it is used for recipient mail)
|
||||
lib.stdheader.20.if {
|
||||
isFalse = 0
|
||||
isFalse.override = 1
|
||||
isFalse.override {
|
||||
if.equals.field = CType
|
||||
if.value = mailform
|
||||
}
|
||||
}
|
||||
|
||||
# ******************
|
||||
# CType: mailform
|
||||
# ******************
|
||||
tt_content.mailform = COA
|
||||
tt_content.mailform.10 = < lib.stdheader
|
||||
tt_content.mailform.20 = FORM
|
||||
tt_content.mailform.20 {
|
||||
useDefaultContentObject = 1
|
||||
accessibility = 1
|
||||
noWrapAttr = 1
|
||||
formName = mailform
|
||||
dontMd5FieldNames = 1
|
||||
layout = <div class="csc-mailform-field">###LABEL### ###FIELD###</div>
|
||||
labelWrap.wrap = |
|
||||
commentWrap.wrap = |
|
||||
radioWrap.wrap = |<br />
|
||||
radioWrap.accessibilityWrap = <fieldset###RADIO_FIELD_ID###><legend>###RADIO_GROUP_LABEL###</legend>|</fieldset>
|
||||
REQ = 1
|
||||
REQ.labelWrap.wrap = |
|
||||
COMMENT.layout = <div class="csc-mailform-label">###LABEL###</div>
|
||||
RADIO.layout = <div class="csc-mailform-field">###LABEL### <span class="csc-mailform-radio">###FIELD###</span></div>
|
||||
LABEL.layout = <div class="csc-mailform-field">###LABEL### <span class="csc-mailform-label">###FIELD###</span></div>
|
||||
target < lib.parseTarget
|
||||
target =
|
||||
target.override = {$styles.content.mailform.target}
|
||||
goodMess = {$styles.content.mailform.goodMess}
|
||||
badMess = {$styles.content.mailform.badMess}
|
||||
redirect.field = pages
|
||||
redirect.listNum = 0
|
||||
recipient.field = subheader
|
||||
data.field = bodytext
|
||||
locationData = 1
|
||||
hiddenFields.stdWrap.wrap = <div style="display:none;">|</div>
|
||||
|
||||
params.radio = class="csc-mailform-radio"
|
||||
params.check = class="csc-mailform-check"
|
||||
params.submit = class="csc-mailform-submit"
|
||||
|
||||
stdWrap.wrap = <fieldset class="csc-mailform"> | </fieldset>
|
||||
stdWrap {
|
||||
editIcons = tt_content: bodytext, pages, subheader
|
||||
editIcons.iconTitle.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:eIcon.form
|
||||
|
||||
prefixComment = 2 | Mail form inserted:
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
styles.content.searchform {
|
||||
# cat=content/cSearch; type=; label= Message, Searchform: This is the message (if any) that is popped-up when a user performs a search
|
||||
goodMess =
|
||||
}
|
||||
|
||||
styles.content.searchresult {
|
||||
resultTarget = {$PAGE_TARGET}
|
||||
target = {$PAGE_TARGET}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
# ******************
|
||||
# CType: search
|
||||
# ******************
|
||||
tt_content.search = COA
|
||||
tt_content.search.10 = < lib.stdheader
|
||||
# Result:
|
||||
tt_content.search.20 = SEARCHRESULT
|
||||
tt_content.search.20 {
|
||||
allowedCols = pages.title-subtitle-keywords-description : tt_content.header-bodytext-imagecaption : tt_address.name-title-address-email-company-city-country : tt_links.title-note-note2-url : tt_board.subject-message-author-email : tt_calender.title-note : tt_products.title-note-itemnumber
|
||||
languageField.tt_content = sys_language_uid
|
||||
renderObj = COA
|
||||
renderObj {
|
||||
|
||||
10 = TEXT
|
||||
10.field = pages_title
|
||||
10.htmlSpecialChars = 1
|
||||
10.typolink {
|
||||
parameter.field = uid
|
||||
target < lib.parseTarget
|
||||
target =
|
||||
target.override = {$styles.content.searchresult.resultTarget}
|
||||
additionalParams.data = register:SWORD_PARAMS
|
||||
additionalParams.required = 1
|
||||
additionalParams.wrap = &no_cache=1
|
||||
}
|
||||
10.htmlSpecialChars = 1
|
||||
10.wrap = <h3 class="csc-searchResultHeader">|</h3>
|
||||
|
||||
20 = COA
|
||||
20 {
|
||||
10 = TEXT
|
||||
10.field = tt_content_bodytext
|
||||
10.stripHtml = 1
|
||||
10.htmlSpecialChars = 1
|
||||
}
|
||||
20.stdWrap.crop = 200 | ...
|
||||
20.stdWrap.wrap = <p class="csc-searchResult">|</p>
|
||||
}
|
||||
|
||||
layout = COA
|
||||
layout {
|
||||
wrap = <table border="0" cellspacing="0" cellpadding="2" class="csc-searchResultInfo"><tr> | </tr></table> ###RESULT###
|
||||
|
||||
10 = TEXT
|
||||
10.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.resultRange
|
||||
10.wrap = <td class="csc-searchResultRange"><p>|</p></td>
|
||||
|
||||
20 = TEXT
|
||||
20.value = ###PREV### ###NEXT###
|
||||
20.wrap = <td class="csc-searchResultPrevNext"><p>|</p></td>
|
||||
}
|
||||
|
||||
noResultObj = COA
|
||||
noResultObj {
|
||||
10 = TEXT
|
||||
10.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.emptySearch
|
||||
10.wrap = <h3 class="csc-noSearchResultMsg">|</h3>
|
||||
}
|
||||
|
||||
next = TEXT
|
||||
next.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.searchResultNext
|
||||
|
||||
prev = TEXT
|
||||
prev.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.searchResultPrev
|
||||
|
||||
target < lib.parseTarget
|
||||
target =
|
||||
target.override = {$styles.content.searchresult.target}
|
||||
|
||||
range = 20
|
||||
|
||||
stdWrap.prefixComment = 2 | Search result:
|
||||
}
|
||||
|
||||
tt_content.search.30 < tt_content.mailform.20
|
||||
tt_content.search.30 {
|
||||
goodMess = {$styles.content.searchform.goodMess}
|
||||
redirect >
|
||||
recipient >
|
||||
data >
|
||||
dataArray {
|
||||
10.label.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.searchWord
|
||||
10.type = sword=input
|
||||
20.label.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.searchIn
|
||||
20.type = scols=select
|
||||
20.valueArray {
|
||||
10.label.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.headersKeywords
|
||||
10.value = pages.title-subtitle-keywords-description:tt_content.header
|
||||
20.label.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.pageContent
|
||||
20.value = tt_content.header-bodytext-imagecaption
|
||||
}
|
||||
30.type = stype=hidden
|
||||
30.value = L0
|
||||
40.type = submit=submit
|
||||
40.value.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:search.searchButton
|
||||
}
|
||||
type.field = pages
|
||||
type.listNum = 0
|
||||
locationData = HTTP_POST_VARS
|
||||
no_cache = 1
|
||||
|
||||
stdWrap.wrap = <table border="0" cellspacing="1" cellpadding="1" class="csc-searchform"> | </table>
|
||||
stdWrap {
|
||||
editIcons.iconTitle.data = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:eIcon.search
|
||||
|
||||
prefixComment = 2 | Search form inserted:
|
||||
}
|
||||
}
|
||||
1092
typo3conf/ext/compatibility6/Migrations/Code/ClassAliasMap.php
Normal file
1092
typo3conf/ext/compatibility6/Migrations/Code/ClassAliasMap.php
Normal file
File diff suppressed because it is too large
Load Diff
9815
typo3conf/ext/compatibility6/Migrations/Code/LegacyClassesForIde.php
Normal file
9815
typo3conf/ext/compatibility6/Migrations/Code/LegacyClassesForIde.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415224810" source-language="en" datatype="plaintext" original="messages" date="2015-06-20T14:22:32Z" product-name="compatibility6">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="setPageTSconfig">
|
||||
<source>Set PageTSconfig by default: If you are going to use this extension by default in this database then set this flag. In that case you don't need to set specific PageTSconfig for each page, which you have to do otherwise!</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1446137224" source-language="en" datatype="plaintext" original="messages" date="2015-10-29T17:46:32Z" product-name="compatibility6">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="forms_mail_title">
|
||||
<source>Mail Form</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_mail_description">
|
||||
<source>A mail form allowing website users to submit responses.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_search_title">
|
||||
<source>Search Form</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_search_description">
|
||||
<source>Draws a search form and the search result if a search is performed.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="closeDoc">
|
||||
<source>Close</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="saveDoc">
|
||||
<source>Save</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="saveCloseDoc">
|
||||
<source>Save and close</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="labels.changeInOrig">
|
||||
<source>Changed in original translation</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="storage_pid">
|
||||
<source>General Record Storage page:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.storage_pid_formlabel" xml:space="preserve">
|
||||
<source>Page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.palettes.storage" xml:space="preserve">
|
||||
<source>General Record Storage Page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="LGL.default_value">
|
||||
<source>Default</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="LGL.caption">
|
||||
<source>Caption:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="eIcon.form">
|
||||
<source>Edit email form</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="eIcon.search">
|
||||
<source>Edit search element</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.resultRange">
|
||||
<source>Searchresult: ###RANGELOW###-###RANGEHIGH### of ###TOTAL###</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.emptySearch">
|
||||
<source>Sorry, your search was empty!</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.searchResultNext">
|
||||
<source>Next</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.searchResultPrev">
|
||||
<source>Prev</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.searchWord">
|
||||
<source>Searchword:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.searchIn">
|
||||
<source>Search in:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.headersKeywords">
|
||||
<source>Headers and keywords</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.pageContent">
|
||||
<source>Page content</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="search.searchButton">
|
||||
<source>Search now!</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,911 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415814791" source-language="en" datatype="plaintext" original="messages" date="2011-10-17T20:22:32Z" product-name="cms">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="CType_formlabel">
|
||||
<source>Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.0">
|
||||
<source>Header</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.1">
|
||||
<source>Text</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.2">
|
||||
<source>Text & Images</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.3">
|
||||
<source>Images</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.4">
|
||||
<source>Bullet List</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.5">
|
||||
<source>Table</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.6">
|
||||
<source>File Links</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.8">
|
||||
<source>Form</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.9">
|
||||
<source>Search</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.10">
|
||||
<source>Login</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.11">
|
||||
<source>Textbox</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.12">
|
||||
<source>Special Menus</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.13">
|
||||
<source>Insert Records</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.14">
|
||||
<source>Insert Plugin</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.15">
|
||||
<source>Script</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.16">
|
||||
<source>Divider</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.I.17">
|
||||
<source>HTML</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.div.standard">
|
||||
<source>Standard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.div.lists">
|
||||
<source>Lists</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.div.forms">
|
||||
<source>Forms</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="CType.div.special">
|
||||
<source>Special</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="layout.I.1">
|
||||
<source>Layout 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="layout.I.2">
|
||||
<source>Layout 2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="layout.I.3">
|
||||
<source>Layout 3</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colPos">
|
||||
<source>Columns:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colPos_formlabel">
|
||||
<source>Column</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colPos.I.0">
|
||||
<source>Left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colPos.I.1">
|
||||
<source>Normal</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colPos.I.2">
|
||||
<source>Right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colPos.I.3">
|
||||
<source>Border</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="date">
|
||||
<source>Date</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="date_formlabel">
|
||||
<source>Date</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header">
|
||||
<source>Header:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_formlabel">
|
||||
<source>Header</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.ALT.shortcut_formlabel">
|
||||
<source>Name (not visible in frontend)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.ALT.script_formlabel">
|
||||
<source>Name (not visible in frontend)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.ALT.div_formlabel">
|
||||
<source>Name (not visible in frontend)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.ALT.html_formlabel">
|
||||
<source>Name (not visible in frontend)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_position">
|
||||
<source>Align:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_position_formlabel">
|
||||
<source>Alignment</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_position.I.1">
|
||||
<source>Center</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_position.I.2">
|
||||
<source>Right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_position.I.3">
|
||||
<source>Left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_link">
|
||||
<source>Link:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_link_formlabel">
|
||||
<source>Link</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout_formlabel">
|
||||
<source>Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout.I.1">
|
||||
<source>Layout 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout.I.2">
|
||||
<source>Layout 2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout.I.3">
|
||||
<source>Layout 3</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout.I.4">
|
||||
<source>Layout 4</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout.I.5">
|
||||
<source>Layout 5</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="header_layout.I.6">
|
||||
<source>Hidden</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.W.RTE">
|
||||
<source>Fullscreen Rich Text Editing</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.W.table">
|
||||
<source>Table Wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.W.forms">
|
||||
<source>Forms wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagewidth">
|
||||
<source>Width (pixels):</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagewidth_formlabel">
|
||||
<source>Width (px)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageheight">
|
||||
<source>Height (pixels):</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageheight_formlabel">
|
||||
<source>Height (px)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient">
|
||||
<source>Position:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient_formlabel">
|
||||
<source>Position and Alignment</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.0">
|
||||
<source>Above, center</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.1">
|
||||
<source>Above, right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.2">
|
||||
<source>Above, left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.3">
|
||||
<source>Below, center</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.4">
|
||||
<source>Below, right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.5">
|
||||
<source>Below, left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.6">
|
||||
<source>In text, right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.7">
|
||||
<source>In text, left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.8">
|
||||
<source>__No wrap:__</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.9">
|
||||
<source>Beside Text, Right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageorient.I.10">
|
||||
<source>Beside Text, Left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageborder">
|
||||
<source>Border:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imageborder_formlabel">
|
||||
<source>Border</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_noRows">
|
||||
<source>No Rows:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_noRows.I.0">
|
||||
<source>Deactivate</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_noRows_formlabel">
|
||||
<source>Display as Rows</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_link">
|
||||
<source>Link:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_link_formlabel">
|
||||
<source>Links (one per line, one link per image)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_zoom">
|
||||
<source>Click-enlarge:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_zoom_formlabel">
|
||||
<source>Enlarge on Click</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects">
|
||||
<source>Effects:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects_formlabel">
|
||||
<source>Effect</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.0">
|
||||
<source>None</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.1">
|
||||
<source>Rotate 90 CW</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.2">
|
||||
<source>Rotate -90 CCW</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.3">
|
||||
<source>Rotate 180</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.4">
|
||||
<source>Grayscale</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.5">
|
||||
<source>Sharpen</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.6">
|
||||
<source>Normalize</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.7">
|
||||
<source>Contrast</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.8">
|
||||
<source>Brighter</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_effects.I.9">
|
||||
<source>Darker</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames">
|
||||
<source>Frames:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames_formlabel">
|
||||
<source>Graphical Frames</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.0">
|
||||
<source>(None)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.1">
|
||||
<source>Frame 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.2">
|
||||
<source>Frame 2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.3">
|
||||
<source>Frame 3</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.4">
|
||||
<source>Frame 4</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.5">
|
||||
<source>Frame 5</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.6">
|
||||
<source>Frame 6</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.7">
|
||||
<source>Frame 7</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_frames.I.8">
|
||||
<source>Frame 8</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression">
|
||||
<source>Image Quality/Processing:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression_formlabel">
|
||||
<source>Quality and Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression.I.1">
|
||||
<source>None (ignores all other options)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression.I.15">
|
||||
<source>JPG/Very High</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression.I.16">
|
||||
<source>JPG/High</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression.I.17">
|
||||
<source>JPG/Medium</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression.I.18">
|
||||
<source>JPG/Low</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_compression.I.19">
|
||||
<source>JPG/Very Low</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecols">
|
||||
<source>Columns:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecols_formlabel">
|
||||
<source>Number of Columns</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption_position">
|
||||
<source>Align:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption_position_formlabel">
|
||||
<source>Caption Alignment</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption_position.I.1">
|
||||
<source>Center</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption_position.I.2">
|
||||
<source>Right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption_position.I.3">
|
||||
<source>Left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_altText">
|
||||
<source>Alternative Text:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="altText_formlabel">
|
||||
<source>Alternative Labels (one per line)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_titleText">
|
||||
<source>Title Text:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="titleText_formlabel">
|
||||
<source>Titles (one per line)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_longdescURL">
|
||||
<source>Long Description URL:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="images.addFileReference">
|
||||
<source>Add image</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="longdescURL_formlabel">
|
||||
<source>Long Description URLs (one per line)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="cols">
|
||||
<source>Columns</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="cols.I.0">
|
||||
<source>Auto</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recursive.I.0">
|
||||
<source>0 levels (only selected page)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recursive.I.1">
|
||||
<source>1 level</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recursive.I.2">
|
||||
<source>2 levels</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recursive.I.3">
|
||||
<source>3 levels</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recursive.I.4">
|
||||
<source>4 levels</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="recursive.I.5">
|
||||
<source>Infinite</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type">
|
||||
<source>Menu Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type_formlabel">
|
||||
<source>Menu Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.0">
|
||||
<source>Menu of selected pages</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.1">
|
||||
<source>Menu of subpages of selected pages</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.2">
|
||||
<source>Menu of subpages of selected pages including abstracts</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.3">
|
||||
<source>Menu of subpages of selected pages including sections</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.4">
|
||||
<source>Sitemap</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.5">
|
||||
<source>Section index (page content marked for section menus)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.6">
|
||||
<source>Recently updated pages</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.7">
|
||||
<source>Related pages (based on keywords)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.8">
|
||||
<source>Sitemaps of selected pages</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.categorized_pages">
|
||||
<source>Pages for selected categories</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu_type.I.categorized_content">
|
||||
<source>Content elements for selected categories</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="list_type">
|
||||
<source>Plugin:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="list_type_formlabel">
|
||||
<source>Selected Plugin</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor">
|
||||
<source>Backgr. Color:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor_formlabel">
|
||||
<source>Background color</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.1">
|
||||
<source>Color 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.2">
|
||||
<source>Color 2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.3">
|
||||
<source>None</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.5">
|
||||
<source>Black</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.6">
|
||||
<source>White</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.7">
|
||||
<source>Dark Gray</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.8">
|
||||
<source>Gray</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bgColor.I.9">
|
||||
<source>Silver</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_border">
|
||||
<source>Border:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_border_formlabel">
|
||||
<source>Border Size (px)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_cellspacing">
|
||||
<source>Cellspacing:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_cellspacing_formlabel">
|
||||
<source>Cellspacing (px)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_cellpadding">
|
||||
<source>Cellpadding:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_cellpadding_formlabel">
|
||||
<source>Cellpadding (px)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="media">
|
||||
<source>Files</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="media.dataAttributes">
|
||||
<source>Additional data-* Attributes for HTML5 video tag</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="media.dataAttributes.attributeName">
|
||||
<source>Name of attribute (without data-)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="media.dataAttributes.content">
|
||||
<source>Content</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="media.ALT.uploads_formlabel">
|
||||
<source>Select single files</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="media.addFileReference">
|
||||
<source>Add file</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="multimedia">
|
||||
<source>File:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="multimedia_formlabel">
|
||||
<source>Selected Media File</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="file_collections">
|
||||
<source>File collections</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="file_collections.ALT.uploads_formlabel">
|
||||
<source>Select file collections</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_size">
|
||||
<source>Show File Size:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_sorting">
|
||||
<source>Sort Filelist:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_sorting.none">
|
||||
<source>none</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_sorting.extension">
|
||||
<source>by Fileextension</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_sorting.name">
|
||||
<source>by Filename</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_sorting.type">
|
||||
<source>by Filetype</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_sorting.size">
|
||||
<source>by Filesize</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="filelink_size_formlabel">
|
||||
<source>Display File Size Information</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="target">
|
||||
<source>Target:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="target.I.1">
|
||||
<source>New window</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="records">
|
||||
<source>Items:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="records_formlabel">
|
||||
<source>Records</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="spaceBefore">
|
||||
<source>Before:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="spaceBefore_formlabel">
|
||||
<source>Top Margin</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="spaceAfter">
|
||||
<source>After:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="spaceAfter_formlabel">
|
||||
<source>Bottom Margin</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame">
|
||||
<source>Frame:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame_formlabel">
|
||||
<source>Indentation and Frames</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.1">
|
||||
<source>Invisible</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.2">
|
||||
<source>Ruler Before</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.3">
|
||||
<source>Ruler After</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.4">
|
||||
<source>Indent</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.5">
|
||||
<source>Indent, 33/66%</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.6">
|
||||
<source>Indent, 66/33%</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.7">
|
||||
<source>Frame 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="section_frame.I.8">
|
||||
<source>Frame 2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout">
|
||||
<source>Textbox Type:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout_formlabel">
|
||||
<source>Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout.I.1">
|
||||
<source>Image Shadow</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout.I.2">
|
||||
<source>Image Frame 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout.I.3">
|
||||
<source>Image Frame 2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout.I.4">
|
||||
<source>__Graphical:__</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="splash_layout.I.5">
|
||||
<source>Postit 1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sectionIndex">
|
||||
<source>Index:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sectionIndex_formlabel">
|
||||
<source>Show in Section Menus</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="linkToTop">
|
||||
<source>To top:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="linkToTop_formlabel">
|
||||
<source>Append with Link to Top of Page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="rte_enabled">
|
||||
<source>Disable Rich Text Editor:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="rte_enabled_formlabel">
|
||||
<source>Rich Text Editor</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="rte_enabled.I.0">
|
||||
<source>Disable</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pi_flexform">
|
||||
<source>Plugin Options</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="accessibility_title">
|
||||
<source>Block title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="accessibility_bypass">
|
||||
<source>Add link to bypass block</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="accessibility_bypass_text">
|
||||
<source>Link text to bypass block</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="selected_categories">
|
||||
<source>Selected categories</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="category_field">
|
||||
<source>Category field</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="ALT.imgOptions">
|
||||
<source>Image Options</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="ALT.imgLinks">
|
||||
<source>Image Links</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="ALT.imgDimensions">
|
||||
<source>Image Dimensions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="select_key_formlabel">
|
||||
<source>Plugin Mode</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="select_key.ALT.uploads">
|
||||
<source>Read from Path:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="select_key.ALT.uploads_formlabel">
|
||||
<source>Path</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="select_key.ALT.script_formlabel">
|
||||
<source>PHP Code</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption.ALT.uploads">
|
||||
<source>Descriptions:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption.ALT.uploads_formlabel">
|
||||
<source>File Descriptions (one per line)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption.ALT.script">
|
||||
<source>Comments:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.mailform">
|
||||
<source>Configuration:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.mailform_formlabel">
|
||||
<source>Form Structure</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.mailform">
|
||||
<source>Target Page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.searchform">
|
||||
<source>Target page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.loginform">
|
||||
<source>Selected pages: Target (1st), Frontend user container (2nd)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.search">
|
||||
<source>Send to Page:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.login">
|
||||
<source>Send to Page:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.menu_formlabel">
|
||||
<source>Selected Pages</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.list_formlabel">
|
||||
<source>Record Storage Page</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pages.ALT.script_formlabel">
|
||||
<source>Starting Point for This Script</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="subheader.ALT.mailform">
|
||||
<source>Recipient Email:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="subheader.ALT.mailform_formlabel">
|
||||
<source>Recipient Email</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.html">
|
||||
<source>HTML:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu.ALT.accessibility_title_formlabel">
|
||||
<source>Menu block title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu.ALT.accessibility_bypass_formlabel">
|
||||
<source>Add link to bypass navigation block</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="menu.ALT.accessibility_bypass_text_formlabel">
|
||||
<source>Link text to bypass navigation block</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.text">
|
||||
<source>Text</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.media">
|
||||
<source>Media</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.plugin">
|
||||
<source>Plugin</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sys_language_uid_formlabel">
|
||||
<source>Language</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="subheader_formlabel">
|
||||
<source>Subheader</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="hidden_formlabel">
|
||||
<source>Content Element</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="hidden.I.0">
|
||||
<source>Disable</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="starttime_formlabel">
|
||||
<source>Publish Date</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="endtime_formlabel">
|
||||
<source>Expiration Date</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="fe_group_formlabel">
|
||||
<source>Usergroup Access Rights</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="layout_formlabel">
|
||||
<source>Layout</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext_formlabel">
|
||||
<source>Text</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.bulletlist_formlabel">
|
||||
<source>Bullet List</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.table_formlabel">
|
||||
<source>Table Structure</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.media_formlabel">
|
||||
<source>Alternative Content</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.textbox_formlabel">
|
||||
<source>Text</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.script_formlabel">
|
||||
<source>Parameters to pass to the script</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="bodytext.ALT.html_formlabel">
|
||||
<source>HTML Code</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image_formlabel">
|
||||
<source>Images</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="image.ALT.textbox_formlabel">
|
||||
<source>Image Files</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption_formlabel">
|
||||
<source>Captions (one per line)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imagecaption.ALT.script_formlabel">
|
||||
<source>Comments</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="field.default.hidden">
|
||||
<source>Visibility of content element</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="field.table.bodytext">
|
||||
<source>Table content</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.general">
|
||||
<source>Content Element</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.headers">
|
||||
<source>Headlines</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.header">
|
||||
<source>Header</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.visibility">
|
||||
<source>Visibility</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.access">
|
||||
<source>Publish Dates and Access Rights</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.frames">
|
||||
<source>Content Element Layout</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.textlayout">
|
||||
<source>Text Layout</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.imagefiles">
|
||||
<source>Images and Captions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.imagelinks">
|
||||
<source>Behavior</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.image_accessibility">
|
||||
<source>Accessibility</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.image_settings">
|
||||
<source>Image Adjustments</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.imageblock">
|
||||
<source>Image Alignment</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.mailform">
|
||||
<source>Target and Recipient</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.searchform">
|
||||
<source>Search Results</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.loginform">
|
||||
<source>Redirect Target and Frontend User Container</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.multimediafiles">
|
||||
<source>Media Files and Parameters</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.textbox">
|
||||
<source>Render Text into Images</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.menu">
|
||||
<source>Menu and Sitemap</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.menu_accessibility">
|
||||
<source>Accessibility</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.uploads_layout">
|
||||
<source>Filelinks Layout</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.table_layout">
|
||||
<source>Table Layout</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="palette.appearanceLinks">
|
||||
<source>Links</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.access">
|
||||
<source>Access</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.appearance">
|
||||
<source>Appearance</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.behaviour">
|
||||
<source>Behaviour</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.script">
|
||||
<source>Script</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.images">
|
||||
<source>Images</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.extended">
|
||||
<source>Extended</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tabs.accessibility">
|
||||
<source>Accessibility</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,335 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415814890" source-language="en" datatype="plaintext" original="messages" date="2011-10-17T20:22:34Z" product-name="lang">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="rte_undoLastChange">
|
||||
<source>Undo/Redo last change (%s ago)</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop">
|
||||
<source>TypoScript property lookup</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_TSref">
|
||||
<source>TSref online</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_tsconfig">
|
||||
<source>TSconfig online</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_title">
|
||||
<source>Object title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_prefix">
|
||||
<source>Object prefix</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_mixer_indent">
|
||||
<source>Indent +2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_mixer_outdent">
|
||||
<source>Outdent -2</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_mixer_wrap">
|
||||
<source>Wrap</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_mixer_transfer">
|
||||
<source>Transfer & Close</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tsprop_addToList">
|
||||
<source>Add to list...</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_title">
|
||||
<source>Table wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_smallFields">
|
||||
<source>Small fields</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_addColumn">
|
||||
<source>Add column to the right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_removeColumn">
|
||||
<source>Remove column</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_addRow">
|
||||
<source>Add row below</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_removeRow">
|
||||
<source>Remove row</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_left">
|
||||
<source>Move left</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_right">
|
||||
<source>Move right</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_up">
|
||||
<source>Move up</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_down">
|
||||
<source>Move down</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_top">
|
||||
<source>Move to top</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_bottom">
|
||||
<source>Move to bottom</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_start">
|
||||
<source>Move to first column</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_end">
|
||||
<source>Move to last column</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="table_noData">
|
||||
<source>No table,field or uid given</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_title">
|
||||
<source>Forms wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_refresh">
|
||||
<source>Refresh without saving</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_label">
|
||||
<source>Label</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type">
|
||||
<source>Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_textarea">
|
||||
<source>Text area</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_input">
|
||||
<source>Input field</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_password">
|
||||
<source>Password field</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_file">
|
||||
<source>File upload</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_check">
|
||||
<source>Check box</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_select">
|
||||
<source>Selector box</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_radio">
|
||||
<source>Radio buttons</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_hidden">
|
||||
<source>Hidden value</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_submit">
|
||||
<source>Submit Button</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_property">
|
||||
<source>Property</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_type_label">
|
||||
<source>Label</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_required">
|
||||
<source>Required</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_fieldName">
|
||||
<source>Field</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_cols">
|
||||
<source>Columns</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_rows">
|
||||
<source>Rows</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_size">
|
||||
<source>Size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_max">
|
||||
<source>Max</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_autosize">
|
||||
<source>Auto size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_extra">
|
||||
<source>No Wrap</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_default">
|
||||
<source>Value</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_multiple">
|
||||
<source>Multiple</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_options">
|
||||
<source>List options</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_checked">
|
||||
<source>Checked</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_preview">
|
||||
<source>Preview of element</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_element">
|
||||
<source>Element type</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_config">
|
||||
<source>Detailed configuration</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_eform_subject">
|
||||
<source>Subject</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_eform_recipient">
|
||||
<source>Recipient email</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_eform_html_enabled">
|
||||
<source>HTML mode enabled</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_eform_formtype_mail">
|
||||
<source>Send button label</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="forms_special_eform">
|
||||
<source>Special configuration for mail forms</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_title">
|
||||
<source>Color Picker</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_setClose">
|
||||
<source>Save and Close</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_colorValue">
|
||||
<source>Selected Color:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_fromImage">
|
||||
<source>Capture color from image (click on image):</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_fromMatrix">
|
||||
<source>Select color from matrix (websafe colors):</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_fromList">
|
||||
<source>Select HTML color name:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_black">
|
||||
<source>BLACK</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="colorpicker_white">
|
||||
<source>WHITE</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_windowTitle">
|
||||
<source>Set cell name and column number</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_labelName">
|
||||
<source>Name</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_labelColumn">
|
||||
<source>Column Number</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_labelSave">
|
||||
<source>Save to cell</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_addColumn">
|
||||
<source>Add column</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_removeColumn">
|
||||
<source>Remove column</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_addRow">
|
||||
<source>Add row</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_removeRow">
|
||||
<source>Remove row</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_editCell">
|
||||
<source>Edit cell</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_mergeCell">
|
||||
<source>Combine with next cell</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_splitCell">
|
||||
<source>Split cell</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_name">
|
||||
<source>Name</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_column">
|
||||
<source>Column number</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_notSet">
|
||||
<source>not set</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_nameHelp">
|
||||
<source>Enter a name for the cell.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="grid_columnHelp">
|
||||
<source>The column position defines in which area the content is rendered in the frontend.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.open-editor">
|
||||
<source>Open Editor</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.supported-types-message">
|
||||
<source>Image manipulation is only available for supported types:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.no-image-found">
|
||||
<source>No image found</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.no-image-found-message">
|
||||
<source>No image found. Could also be that image is present but that the original dimensions are unknow.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.image-manipulation">
|
||||
<source>Image manipulation</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.image-title">
|
||||
<source>Title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.original-dimensions">
|
||||
<source>Original dimensions</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.reset">
|
||||
<source>Reset</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.accept">
|
||||
<source>Accept</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.cancel">
|
||||
<source>Cancel</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.aspect-ratio">
|
||||
<source>Aspect ratio</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.set-aspect-ratio">
|
||||
<source>Set Aspect Ratio</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.ratio.16_9">
|
||||
<source>16:9</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.ratio.4_3">
|
||||
<source>4:3</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.ratio.1_1">
|
||||
<source>1:1</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.ratio.free">
|
||||
<source>Free</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.zoom">
|
||||
<source>Zoom</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.zoom-in">
|
||||
<source>Zoom in</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.zoom-out">
|
||||
<source>Zoom out</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.selection">
|
||||
<source>Selected Size</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.crop-x">
|
||||
<source>x:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.crop-y">
|
||||
<source>y:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.crop-width">
|
||||
<source>width:</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="imwizard.crop-height">
|
||||
<source>height:</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415814826" source-language="en" datatype="plaintext" original="messages" date="2011-10-17T20:22:33Z" product-name="compatibility6">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="wiz_lWizards">
|
||||
<source>Select Wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="mod_wizards">
|
||||
<source>Wizards</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff version="1.0" xmlns:t3="http://typo3.org/schemas/xliff">
|
||||
<file t3:id="1415814827" source-language="en" datatype="plaintext" original="messages" date="2011-10-17T20:22:33Z" product-name="compatibility6">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="tx_funcwizards.alttitle">
|
||||
<source>Page Wizards</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_funcwizards.description">
|
||||
<source>This submodule provides a framework where wizards can be added. Available wizards currently include a wizard for creating pages and sorting pages by title etc.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="_tx_funcwizards.seeAlso" xml:space="preserve">
|
||||
<source>_MOD_web_func:tx_wizardcrpages,
|
||||
_MOD_web_func:tx_wizardsortpages</source>
|
||||
<note from="developer">This string contains an internal text, which must not be changed. Just copy the original text into the translation field. For more information have a look at the Tutorial.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,70 @@
|
||||
<!-- ###FULLDOC### begin -->
|
||||
<div class="typo3-fullDoc">
|
||||
<div id="typo3-docheader">
|
||||
<div class="typo3-docheader-functions">
|
||||
<div class="left">###CSH###</div>
|
||||
<div class="right"></div>
|
||||
</div>
|
||||
<div class="typo3-docheader-buttons">
|
||||
<div class="left">###BUTTONLIST_LEFT###</div>
|
||||
<div class="right">###BUTTONLIST_RIGHT###</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="typo3-docbody">
|
||||
<div id="typo3-inner-docbody">
|
||||
###CONTENT###
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ###FULLDOC### end -->
|
||||
|
||||
<!-- Grouping the icons on top -->
|
||||
|
||||
<!-- ###BUTTON_GROUP_WRAP### -->
|
||||
<div class="buttongroup">###BUTTONS###</div>
|
||||
<!-- ###BUTTON_GROUP_WRAP### -->
|
||||
|
||||
<!-- ###BUTTON_GROUPS_LEFT### -->
|
||||
<!-- ###BUTTON_GROUP1### -->###CLOSE###<!-- ###BUTTON_GROUP1### -->
|
||||
<!-- ###BUTTON_GROUP2### -->###SAVE######SAVE_CLOSE###<!-- ###BUTTON_GROUP2### -->
|
||||
<!-- ###BUTTON_GROUPS_LEFT### -->
|
||||
|
||||
<!-- ###BUTTON_GROUPS_RIGHT### -->
|
||||
<!-- ###BUTTON_GROUP1### -->###RELOAD###<!-- ###BUTTON_GROUP1### -->
|
||||
<!-- ###BUTTON_GROUPS_RIGHT### -->
|
||||
<!-- ###FULLDOC### begin -->
|
||||
<div class="typo3-fullDoc">
|
||||
<div id="typo3-docheader">
|
||||
<div class="typo3-docheader-functions">
|
||||
<div class="left">###CSH###</div>
|
||||
<div class="right"></div>
|
||||
</div>
|
||||
<div class="typo3-docheader-buttons">
|
||||
<div class="left">###BUTTONLIST_LEFT###</div>
|
||||
<div class="right">###BUTTONLIST_RIGHT###</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="typo3-docbody">
|
||||
<div id="typo3-inner-docbody">
|
||||
###CONTENT###
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ###FULLDOC### end -->
|
||||
|
||||
<!-- Grouping the icons on top -->
|
||||
|
||||
<!-- ###BUTTON_GROUP_WRAP### -->
|
||||
<div class="buttongroup">###BUTTONS###</div>
|
||||
<!-- ###BUTTON_GROUP_WRAP### -->
|
||||
|
||||
<!-- ###BUTTON_GROUPS_LEFT### -->
|
||||
<!-- ###BUTTON_GROUP1### -->###CLOSE###<!-- ###BUTTON_GROUP1### -->
|
||||
<!-- ###BUTTON_GROUP2### -->###SAVE######SAVE_CLOSE###<!-- ###BUTTON_GROUP2### -->
|
||||
<!-- ###BUTTON_GROUPS_LEFT### -->
|
||||
|
||||
<!-- ###BUTTON_GROUPS_RIGHT### -->
|
||||
<!-- ###BUTTON_GROUP1### -->###RELOAD###<!-- ###BUTTON_GROUP1### -->
|
||||
<!-- ###BUTTON_GROUPS_RIGHT### -->
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 582 B |
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
|
||||
function validateForm(theFormname,theFieldlist,goodMess,badMess,emailMess) {
|
||||
var formObject = document[theFormname];
|
||||
if (!formObject) {
|
||||
formObject = document.getElementById(theFormname);
|
||||
}
|
||||
if (formObject && theFieldlist) {
|
||||
var index=1;
|
||||
var theField = split(theFieldlist, ",", index);
|
||||
var msg="";
|
||||
var theEreg = '';
|
||||
var theEregMsg = '';
|
||||
var specialMode = '';
|
||||
var theLabel, a;
|
||||
|
||||
while (theField) {
|
||||
theEreg = '';
|
||||
specialMode = '';
|
||||
|
||||
// Check special modes:
|
||||
if (theField == '_EREG') { // EREG mode: _EREG,[error msg],[JS ereg],[fieldname],[field Label]
|
||||
specialMode = theField;
|
||||
|
||||
index++;
|
||||
theEregMsg = split(theFieldlist, ",", index);
|
||||
index++;
|
||||
theEreg = split(theFieldlist, ",", index);
|
||||
} else if (theField == '_EMAIL') {
|
||||
specialMode = theField;
|
||||
}
|
||||
|
||||
// Get real field name if special mode has been set:
|
||||
if (specialMode) {
|
||||
index++;
|
||||
theField = split(theFieldlist, ",", index);
|
||||
}
|
||||
|
||||
index++;
|
||||
theLabel = split(theFieldlist, ",", index);
|
||||
theField = theField;
|
||||
if (formObject[theField]) {
|
||||
var fObj = formObject[theField];
|
||||
var type=fObj.type;
|
||||
if (!fObj.type) {
|
||||
type="radio";
|
||||
}
|
||||
var value="";
|
||||
switch(type) {
|
||||
case "text":
|
||||
case "textarea":
|
||||
case "password":
|
||||
case "file":
|
||||
value = fObj.value;
|
||||
break;
|
||||
case "select-one":
|
||||
if (fObj.selectedIndex>=0) {
|
||||
value = fObj.options[fObj.selectedIndex].value;
|
||||
}
|
||||
break;
|
||||
case "select-multiple":
|
||||
var l=fObj.length;
|
||||
for (a=0;a<l;a++) {
|
||||
if (fObj.options[a].selected) {
|
||||
value+= fObj.options[a].value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "radio":
|
||||
case "checkbox":
|
||||
var len=fObj.length;
|
||||
if (len) {
|
||||
for (a=0;a<len;a++) {
|
||||
if (fObj[a].checked) {
|
||||
value = fObj[a].value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fObj.checked) {
|
||||
value = fObj.value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
value = 1;
|
||||
}
|
||||
|
||||
switch(specialMode) {
|
||||
case "_EMAIL":
|
||||
var theRegEx_notValid = new RegExp("(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)", "gi");
|
||||
var theRegEx_isValid = new RegExp("^.+\@[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})$","");
|
||||
if (!theRegEx_isValid.test(value)) { // This part was supposed to be a part of the condition: " || theRegEx_notValid.test(value)" - but I couldn't make it work (Mozilla Firefox, linux) - Anyone knows why?
|
||||
msg+="\n"+theLabel+' ('+(emailMess ? emailMess : 'Email address not valid!')+')';
|
||||
}
|
||||
break;
|
||||
case "_EREG":
|
||||
var theRegEx_isValid = new RegExp(theEreg,"");
|
||||
if (!theRegEx_isValid.test(value)) {
|
||||
msg+="\n"+theLabel+' ('+theEregMsg+')';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!value) {
|
||||
msg+="\n"+theLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
theField = split(theFieldlist, ",", index);
|
||||
}
|
||||
if (msg) {
|
||||
var theBadMess = badMess;
|
||||
if (!theBadMess) {
|
||||
theBadMess = "You must fill in these fields:";
|
||||
}
|
||||
theBadMess+="\n";
|
||||
alert(theBadMess+msg);
|
||||
return false;
|
||||
} else {
|
||||
var theGoodMess = goodMess;
|
||||
if (theGoodMess) {
|
||||
alert(theGoodMess);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
function split(theStr1, delim, index) {
|
||||
var theStr = ''+theStr1;
|
||||
var lengthOfDelim = delim.length;
|
||||
var sPos = -lengthOfDelim;
|
||||
var a, ePos;
|
||||
if (index<1) {index=1;}
|
||||
for (a=1; a<index; a++) {
|
||||
sPos = theStr.indexOf(delim, sPos+lengthOfDelim);
|
||||
if (sPos==-1) {return null;}
|
||||
}
|
||||
ePos = theStr.indexOf(delim, sPos+lengthOfDelim);
|
||||
if(ePos == -1) {ePos = theStr.length;}
|
||||
return (theStr.substring(sPos+lengthOfDelim,ePos));
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
26
typo3conf/ext/compatibility6/composer.json
Normal file
26
typo3conf/ext/compatibility6/composer.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "typo3/cms-compatibility6",
|
||||
"type": "typo3-cms-extension",
|
||||
"description": "TYPO3 Core",
|
||||
"homepage": "https://typo3.org",
|
||||
"license": ["GPL-2.0+"],
|
||||
|
||||
"require": {
|
||||
"typo3/cms-core": "*"
|
||||
},
|
||||
"replace": {
|
||||
"compatibility6": "*"
|
||||
},
|
||||
"extra": {
|
||||
"typo3/class-alias-loader": {
|
||||
"class-alias-maps": [
|
||||
"Migrations/Code/ClassAliasMap.php"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"TYPO3\\CMS\\Compatibility6\\": "Classes/"
|
||||
}
|
||||
}
|
||||
}
|
||||
2
typo3conf/ext/compatibility6/ext_conf_template.txt
Normal file
2
typo3conf/ext/compatibility6/ext_conf_template.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# cat=basic/enable; type=boolean; label=LLL:EXT:compatibility6/Resources/Private/Language/extensionmanager.xlf:setPageTSconfig
|
||||
setPageTSconfig = 1
|
||||
40
typo3conf/ext/compatibility6/ext_emconf.php
Normal file
40
typo3conf/ext/compatibility6/ext_emconf.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/***************************************************************
|
||||
* Extension Manager/Repository config file for ext "compatibility6".
|
||||
*
|
||||
* Auto generated 27-01-2016 07:40
|
||||
*
|
||||
* Manual updates:
|
||||
* Only the data in the array - everything else is removed by next
|
||||
* writing. "version" and "dependencies" must not be touched!
|
||||
***************************************************************/
|
||||
|
||||
$EM_CONF[$_EXTKEY] = array (
|
||||
'title' => 'Compatibility Mode for TYPO3 CMS 6.x',
|
||||
'description' => 'Provides an additional backwards-compatibility layer with legacy functionality for sites that haven\'t fully migrated to v7 yet.',
|
||||
'category' => 'be',
|
||||
'state' => 'stable',
|
||||
'uploadfolder' => true,
|
||||
'createDirs' => '',
|
||||
'clearCacheOnLoad' => 0,
|
||||
'author' => 'TYPO3 CMS Team',
|
||||
'author_email' => '',
|
||||
'author_company' => '',
|
||||
'version' => '7.6.0',
|
||||
'constraints' =>
|
||||
array (
|
||||
'depends' =>
|
||||
array (
|
||||
'typo3' => '6.0.0-7.99.99',
|
||||
),
|
||||
'conflicts' =>
|
||||
array (
|
||||
),
|
||||
'suggests' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
'clearcacheonload' => true,
|
||||
);
|
||||
|
||||
BIN
typo3conf/ext/compatibility6/ext_icon.png
Normal file
BIN
typo3conf/ext/compatibility6/ext_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
147
typo3conf/ext/compatibility6/ext_localconf.php
Normal file
147
typo3conf/ext/compatibility6/ext_localconf.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or die();
|
||||
|
||||
// unserializing the configuration so we can use it here:
|
||||
$_EXTCONF = unserialize($_EXTCONF);
|
||||
if (!$_EXTCONF || $_EXTCONF['setPageTSconfig']) {
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('
|
||||
# Removes obsolete type values and fields from "Content Element" table "tt_content"
|
||||
TCEFORM.tt_content.image_frames.disabled = 1
|
||||
');
|
||||
}
|
||||
|
||||
|
||||
// Register language aware flex form handling in FormEngine
|
||||
// Register render elements
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1443361297] = [
|
||||
'nodeName' => 'flex',
|
||||
'priority' => 40,
|
||||
'class' => \TYPO3\CMS\Compatibility6\Form\Container\FlexFormEntryContainer::class,
|
||||
];
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1443361298] = [
|
||||
'nodeName' => 'flexFormNoTabsContainer',
|
||||
'priority' => 40,
|
||||
'class' => \TYPO3\CMS\Compatibility6\Form\Container\FlexFormNoTabsContainer::class,
|
||||
];
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1443361299] = [
|
||||
'nodeName' => 'flexFormTabsContainer',
|
||||
'priority' => 40,
|
||||
'class' => \TYPO3\CMS\Compatibility6\Form\Container\FlexFormTabsContainer::class,
|
||||
];
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1443361300] = [
|
||||
'nodeName' => 'flexFormElementContainer',
|
||||
'priority' => 40,
|
||||
'class' => \TYPO3\CMS\Compatibility6\Form\Container\FlexFormElementContainer::class,
|
||||
];
|
||||
// Unregister stock TcaFlexProcess data provider and substitute with own data provider at the same position
|
||||
unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord']
|
||||
[\TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexProcess::class]
|
||||
);
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord']
|
||||
[\TYPO3\CMS\Compatibility6\Form\FormDataProvider\TcaFlexProcess::class] = [
|
||||
'depends' => [
|
||||
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare::class,
|
||||
]
|
||||
];
|
||||
unset($GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord']
|
||||
[\TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class]['depends'][\TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexProcess::class]
|
||||
);
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord']
|
||||
[\TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class]['depends'][]
|
||||
= \TYPO3\CMS\Compatibility6\Form\FormDataProvider\TcaFlexProcess::class;
|
||||
// Register "XCLASS" of FlexFormTools for language parsing
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class]['className']
|
||||
= TYPO3\CMS\Compatibility6\Configuration\FlexForm\FlexFormTools::class;
|
||||
// Language diff updating in flex
|
||||
$GLOBALS['TYPO3_CONF_VARS']['BE']['flexFormXMLincludeDiffBase'] = true;
|
||||
|
||||
|
||||
// TCA migration if TCA registration still happened in ext_tables.php
|
||||
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'])) {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'] = array();
|
||||
}
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['extTablesInclusion-PostProcessing'][] = \TYPO3\CMS\Compatibility6\Hooks\ExtTablesPostProcessing\TcaMigration::class;
|
||||
|
||||
// Register legacy content objects
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['IMGTEXT'] = \TYPO3\CMS\Compatibility6\ContentObject\ImageTextContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['CLEARGIF'] = \TYPO3\CMS\Compatibility6\ContentObject\ClearGifContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['CTABLE'] = \TYPO3\CMS\Compatibility6\ContentObject\ContentTableContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['OTABLE'] = \TYPO3\CMS\Compatibility6\ContentObject\OffsetTableContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['COLUMNS'] = \TYPO3\CMS\Compatibility6\ContentObject\ColumnsContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['HRULER'] = \TYPO3\CMS\Compatibility6\ContentObject\HorizontalRulerContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['FORM'] = \TYPO3\CMS\Compatibility6\ContentObject\FormContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['SEARCHRESULT'] = \TYPO3\CMS\Compatibility6\ContentObject\SearchResultContentObject::class;
|
||||
// deprecated alias names for cObjects in use
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['COBJ_ARRAY'] = \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayContentObject::class;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['ContentObjects']['CASEFUNC'] = \TYPO3\CMS\Frontend\ContentObject\CaseContentObject::class;
|
||||
|
||||
// Register a hook for data submission
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission']['mailform'] = \TYPO3\CMS\Compatibility6\Controller\FormDataSubmissionController::class;
|
||||
|
||||
// Register hooks for xhtml_cleaning and prefixLocalAnchors
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'][] = \TYPO3\CMS\Compatibility6\Hooks\TypoScriptFrontendController\ContentPostProcHook::class . '->contentPostProcAll';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-cached'][] = \TYPO3\CMS\Compatibility6\Hooks\TypoScriptFrontendController\ContentPostProcHook::class . '->contentPostProcCached';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'][] = \TYPO3\CMS\Compatibility6\Hooks\TypoScriptFrontendController\ContentPostProcHook::class . '->contentPostProcOutput';
|
||||
|
||||
/**
|
||||
* CType "mailform"
|
||||
*/
|
||||
// Only apply fallback to plain old FORM/mailform if extension "form" is not loaded
|
||||
if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('form')) {
|
||||
// Add Default TypoScript for CType "mailform" after default content rendering
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('compatibility6', 'constants', '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:compatibility6/Configuration/TypoScript/Form/constants.txt">', 'defaultContentRendering');
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('compatibility6', 'setup', '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:compatibility6/Configuration/TypoScript/Form/setup.txt">', 'defaultContentRendering');
|
||||
|
||||
// Add the search CType to the "New Content Element" wizard
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('
|
||||
mod.wizards.newContentElement.wizardItems.forms {
|
||||
elements.mailform {
|
||||
iconIdentifier = content-elements-mailform
|
||||
title = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:forms_mail_title
|
||||
description = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:forms_mail_description
|
||||
tt_content_defValues {
|
||||
CType = mailform
|
||||
bodytext (
|
||||
# Example content:
|
||||
Name: | *name = input,40 | Enter your name here
|
||||
Email: | *email=input,40 |
|
||||
Address: | address=textarea,40,5 |
|
||||
Contact me: | tv=check | 1
|
||||
|
||||
|formtype_mail = submit | Send form!
|
||||
|html_enabled=hidden | 1
|
||||
|subject=hidden| This is the subject
|
||||
)
|
||||
}
|
||||
}
|
||||
show :=addToList(mailform)
|
||||
}
|
||||
');
|
||||
|
||||
// Register for hook to show preview of tt_content element of CType="mailform" in page module
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['mailform'] = \TYPO3\CMS\Compatibility6\Hooks\PageLayoutView\MailformPreviewRenderer::class;
|
||||
|
||||
// Register for hook to show preview of tt_content element of CType="script" in page module
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['script'] = \TYPO3\CMS\Compatibility6\Hooks\PageLayoutView\ScriptPreviewRenderer::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* CType "search"
|
||||
*/
|
||||
|
||||
// Add Default TypoScript for CType "search" after default content rendering
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('compatibility6', 'constants', '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:compatibility6/Configuration/TypoScript/Search/constants.txt">', 'defaultContentRendering');
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('compatibility6', 'setup', '<INCLUDE_TYPOSCRIPT: source="FILE:EXT:compatibility6/Configuration/TypoScript/Search/setup.txt">', 'defaultContentRendering');
|
||||
|
||||
// Add the search CType to the "New Content Element" wizard
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('
|
||||
mod.wizards.newContentElement.wizardItems.forms {
|
||||
elements.search {
|
||||
iconIdentifier = content-elements-searchform
|
||||
title = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:forms_search_title
|
||||
description = LLL:EXT:compatibility6/Resources/Private/Language/locallang.xlf:forms_search_description
|
||||
tt_content_defValues.CType = search
|
||||
}
|
||||
show :=addToList(search)
|
||||
}
|
||||
');
|
||||
12
typo3conf/ext/compatibility6/ext_tables.php
Normal file
12
typo3conf/ext/compatibility6/ext_tables.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or die();
|
||||
|
||||
if (TYPO3_MODE === 'BE') {
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::insertModuleFunction(
|
||||
'web_func',
|
||||
\TYPO3\CMS\Compatibility6\Controller\WebFunctionWizardsBaseController::class,
|
||||
null,
|
||||
'LLL:EXT:compatibility6/Resources/Private/Language/wizards.xlf:mod_wizards'
|
||||
);
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('_MOD_web_func', 'EXT:compatibility6/Resources/Private/Language/wizards_csh.xlf');
|
||||
}
|
||||
19
typo3conf/ext/compatibility6/ext_tables.sql
Normal file
19
typo3conf/ext/compatibility6/ext_tables.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# Table structure for table 'tt_content'
|
||||
#
|
||||
CREATE TABLE tt_content (
|
||||
altText text,
|
||||
imagecaption text,
|
||||
imagecaption_position varchar(6) DEFAULT '' NOT NULL,
|
||||
image_link text,
|
||||
image_frames int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
longdescURL text,
|
||||
titleText text
|
||||
);
|
||||
|
||||
#
|
||||
# Table structure for table 'pages'
|
||||
#
|
||||
CREATE TABLE pages (
|
||||
storage_pid int(11) DEFAULT '0' NOT NULL
|
||||
);
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use DmitryDulepov\DdGooglesitemap\Renderers\AbstractSitemapRenderer;
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class is a base for all sitemap generators.
|
||||
*
|
||||
* @author Dmitry Dulepov <support@snowflake.ch>
|
||||
*/
|
||||
abstract class AbstractSitemapGenerator {
|
||||
/**
|
||||
* cObject to generate links
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $cObj;
|
||||
|
||||
/**
|
||||
* Maximum number of items to show.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* Offset to start outputting from.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* A sitemap renderer
|
||||
*
|
||||
* @var AbstractSitemapRenderer
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Class name to instantiate the renderer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rendererClass = 'DmitryDulepov\\DdGooglesitemap\\Renderers\\StandardSitemapRenderer';
|
||||
|
||||
/**
|
||||
* Initializes the instance of this class. This constructir sets starting
|
||||
* point for the sitemap to the current page id
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
|
||||
$this->cObj->start(array());
|
||||
|
||||
$this->offset = max(0, (int)GeneralUtility::_GET('offset'));
|
||||
$this->limit = max(0, (int)GeneralUtility::_GET('limit'));
|
||||
if ($this->limit <= 0) {
|
||||
$this->limit = 50000;
|
||||
}
|
||||
|
||||
$this->createRenderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes sitemap content to the output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main() {
|
||||
header('Content-type: text/xml');
|
||||
if ($this->renderer) {
|
||||
echo $this->renderer->getStartTags();
|
||||
}
|
||||
$this->generateSitemapContent();
|
||||
if ($this->renderer) {
|
||||
echo $this->renderer->getEndTags();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the renderer using $this->rendererClass. Subclasses can use a
|
||||
* more flexible logic if just setting the class is not enough.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function createRenderer() {
|
||||
$this->renderer = GeneralUtility::makeInstance($this->rendererClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the sitemap and echoes it to the browser.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function generateSitemapContent();
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class implements a Google sitemap.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class EntryPoint {
|
||||
|
||||
const DEFAULT_SITEMAP_TYPE = 'pages';
|
||||
|
||||
public function __construct() {
|
||||
@set_time_limit(300);
|
||||
$this->initTSFE();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function of the class. Outputs sitemap.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main() {
|
||||
$sitemapType = $this->getSitemapType();
|
||||
if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['sitemap'][$sitemapType])) {
|
||||
$userFuncRef = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['sitemap'][$sitemapType];
|
||||
$params = array();
|
||||
GeneralUtility::callUserFunction($userFuncRef, $params, $this);
|
||||
}
|
||||
else {
|
||||
header('HTTP/1.0 400 Bad request', true, 400);
|
||||
header('Content-type: text/plain');
|
||||
echo 'No generator found for type \'' . $sitemapType . '\'';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines what sitemap we should send
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSitemapType() {
|
||||
$type = GeneralUtility::_GP('sitemap');
|
||||
return ($type ?: self::DEFAULT_SITEMAP_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes TSFE and sets $GLOBALS['TSFE']
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initTSFE() {
|
||||
$GLOBALS['TSFE'] = $tsfe = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', $GLOBALS['TYPO3_CONF_VARS'], GeneralUtility::_GP('id'), '');
|
||||
/** @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfe */
|
||||
$tsfe->connectToDB();
|
||||
$tsfe->initFEuser();
|
||||
\TYPO3\CMS\Frontend\Utility\EidUtility::initTCA();
|
||||
$tsfe->determineId();
|
||||
$tsfe->initTemplate();
|
||||
$tsfe->getConfigArray();
|
||||
|
||||
// Get linkVars, absRefPrefix, etc
|
||||
\TYPO3\CMS\Frontend\Page\PageGenerator::pagegenInit();
|
||||
}
|
||||
}
|
||||
|
||||
$generator = GeneralUtility::makeInstance('DmitryDulepov\\DdGooglesitemap\\Generator\\EntryPoint');
|
||||
/* @var EntryPoint $generator */
|
||||
$generator->main();
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use DmitryDulepov\DdGooglesitemap\Renderers\AbstractSitemapRenderer;
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class produces sitemap for pages
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
|
||||
class PagesSitemapGenerator extends AbstractSitemapGenerator {
|
||||
|
||||
/**
|
||||
* List of page uid values to generate entries for
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pageList = array();
|
||||
|
||||
/**
|
||||
* Number of generated items.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $generatedItemCount = 0;
|
||||
|
||||
/**
|
||||
* A sitemap renderer
|
||||
*
|
||||
* @var AbstractSitemapRenderer
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/** @var array */
|
||||
protected $excludedPageTypes = array(0, 3, 4, 5, 6, 7, 199, 254, 255);
|
||||
|
||||
/**
|
||||
* Hook objects for post-processing
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hookObjects;
|
||||
|
||||
/**
|
||||
* Initializes the instance of this class. This constructir sets starting
|
||||
* point for the sitemap to the current page id
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$excludePageTypes = GeneralUtility::intExplode(',', $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['excludePageType'], TRUE);
|
||||
if (count($excludePageTypes) > 0) {
|
||||
$this->excludedPageTypes = $excludePageTypes;
|
||||
}
|
||||
|
||||
$pid = intval($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['forceStartPid']);
|
||||
if ($pid === 0 || $pid == $GLOBALS['TSFE']->id) {
|
||||
$this->pageList[$GLOBALS['TSFE']->id] = array(
|
||||
'uid' => $GLOBALS['TSFE']->id,
|
||||
'SYS_LASTCHANGED' => $GLOBALS['TSFE']->page['SYS_LASTCHANGED'],
|
||||
'tx_ddgooglesitemap_lastmod' => $GLOBALS['TSFE']->page['tx_ddgooglesitemap_lastmod'],
|
||||
'tx_ddgooglesitemap_priority' => $GLOBALS['TSFE']->page['tx_ddgooglesitemap_priority'],
|
||||
'doktype' => $GLOBALS['TSFE']->page['doktype'],
|
||||
'no_search' => $GLOBALS['TSFE']->page['no_search']
|
||||
);
|
||||
}
|
||||
else {
|
||||
$page = $GLOBALS['TSFE']->sys_page->getPage($pid);
|
||||
$this->pageList[$page['uid']] = array(
|
||||
'uid' => $page['uid'],
|
||||
'SYS_LASTCHANGED' => $page['SYS_LASTCHANGED'],
|
||||
'tx_ddgooglesitemap_lastmod' => $page['tx_ddgooglesitemap_lastmod'],
|
||||
'tx_ddgooglesitemap_priority' => $page['tx_ddgooglesitemap_priority'],
|
||||
'doktype' => $page['doktype'],
|
||||
'no_search' => $page['no_search']
|
||||
);
|
||||
}
|
||||
|
||||
$this->renderer = GeneralUtility::makeInstance('DmitryDulepov\\DdGooglesitemap\\Renderers\\StandardSitemapRenderer');
|
||||
|
||||
// Prepare user defined objects (if any)
|
||||
$this->hookObjects = array();
|
||||
if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['generateSitemapForPagesClass'])) {
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['generateSitemapForPagesClass'] as $classRef) {
|
||||
$this->hookObjects[] = GeneralUtility::getUserObj($classRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates sitemap for pages (<url> entries in the sitemap)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function generateSitemapContent() {
|
||||
// Workaround: we want the sysfolders back into the menu list!
|
||||
// We also exclude "Backend user section" pages.
|
||||
$GLOBALS['TSFE']->sys_page->where_hid_del = str_replace(
|
||||
'pages.doktype<200',
|
||||
'pages.doktype<>255 AND pages.doktype<>6',
|
||||
$GLOBALS['TSFE']->sys_page->where_hid_del
|
||||
);
|
||||
|
||||
while (!empty($this->pageList) && $this->generatedItemCount - $this->offset <= $this->limit) {
|
||||
$pageInfo = array_shift($this->pageList);
|
||||
if ($this->generatedItemCount >= $this->offset) {
|
||||
$this->writeSingleUrl($pageInfo);
|
||||
}
|
||||
$this->generatedItemCount++;
|
||||
|
||||
// Add subpages of this page to the end of the page list. This way
|
||||
// we get top level pages in the sitemap first, then subpages of the
|
||||
// first, second, etc pages of the top level pages and so on.
|
||||
//
|
||||
// Notice: no sorting (for speed)!
|
||||
$GLOBALS['TSFE']->sys_page->sys_language_uid = $GLOBALS['TSFE']->config['config']['sys_language_uid'];
|
||||
$morePages = $GLOBALS['TSFE']->sys_page->getMenu($pageInfo['uid'],
|
||||
'uid,doktype,no_search,l18n_cfg,SYS_LASTCHANGED,tx_ddgooglesitemap_lastmod,tx_ddgooglesitemap_priority',
|
||||
'', '', false);
|
||||
$this->removeNonTranslatedPages($morePages);
|
||||
$this->pageList = array_merge($this->pageList, array_values($morePages));
|
||||
unset($morePages);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the last modification date of the page.
|
||||
*
|
||||
* @param array $pageInfo
|
||||
* @return int
|
||||
*/
|
||||
protected function getLastMod(array $pageInfo) {
|
||||
$lastModDates = GeneralUtility::intExplode(',', $pageInfo['tx_ddgooglesitemap_lastmod']);
|
||||
$lastModDates[] = intval($pageInfo['SYS_LASTCHANGED']);
|
||||
rsort($lastModDates, SORT_NUMERIC);
|
||||
reset($lastModDates);
|
||||
|
||||
return current($lastModDates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude pages from given list
|
||||
*
|
||||
* @param array $pages
|
||||
* @return void
|
||||
*/
|
||||
protected function removeNonTranslatedPages(array &$pages) {
|
||||
$language = (int)$GLOBALS['TSFE']->config['config']['sys_language_uid'];
|
||||
foreach ($pages as $pageUid => $page) {
|
||||
// Hide page in default language
|
||||
if ($language === 0 && GeneralUtility::hideIfDefaultLanguage($page['l18n_cfg'])) {
|
||||
unset($pages[$pageUid]);
|
||||
}
|
||||
elseif ($language !== 0 && !isset($page['_PAGES_OVERLAY']) && GeneralUtility::hideIfNotTranslated($page['l18n_cfg'])) {
|
||||
// Hide page if no translation is set
|
||||
unset($pages[$pageUid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page should be included into the sitemap.
|
||||
*
|
||||
* @param array $pageInfo
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldIncludePageInSitemap(array $pageInfo) {
|
||||
return !$pageInfo['no_search'] && !in_array($pageInfo['doktype'], $this->excludedPageTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs information about single page
|
||||
*
|
||||
* @param array $pageInfo Page information (needs 'uid' and 'SYS_LASTCHANGED' columns)
|
||||
* @return void
|
||||
*/
|
||||
protected function writeSingleUrl(array $pageInfo) {
|
||||
if ($this->shouldIncludePageInSitemap($pageInfo) && ($url = $this->getPageLink($pageInfo['uid']))) {
|
||||
echo $this->renderer->renderEntry($url, $pageInfo['title'],
|
||||
$this->getLastMod($pageInfo),
|
||||
$this->getChangeFrequency($pageInfo), '', $pageInfo['tx_ddgooglesitemap_priority']);
|
||||
|
||||
// Post-process current page and possibly append data
|
||||
// @see http://forge.typo3.org/issues/45637
|
||||
foreach ($this->hookObjects as $hookObject) {
|
||||
if (is_callable(array($hookObject, 'postProcessPageInfo'))) {
|
||||
$parameters = array(
|
||||
'pageInfo' => &$pageInfo,
|
||||
'generatedItemCount' => &$this->generatedItemCount,
|
||||
'offset' => $this->offset,
|
||||
'limit' => $this->limit,
|
||||
'renderer' => $this->renderer,
|
||||
'pObj' => $this
|
||||
);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$hookObject->postProcessPageInfo($parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getChangeFrequency(array $pageInfo) {
|
||||
$timeValues = GeneralUtility::intExplode(',', $pageInfo['tx_ddgooglesitemap_lastmod']);
|
||||
// Remove zeros
|
||||
foreach ($timeValues as $k => $v) {
|
||||
if ($v == 0) {
|
||||
unset($timeValues[$k]);
|
||||
}
|
||||
}
|
||||
$timeValues[] = $pageInfo['SYS_LASTCHANGED'];
|
||||
$timeValues[] = time();
|
||||
sort($timeValues, SORT_NUMERIC);
|
||||
$sum = 0;
|
||||
for ($i = count($timeValues) - 1; $i > 0; $i--) {
|
||||
$sum += ($timeValues[$i] - $timeValues[$i - 1]);
|
||||
}
|
||||
$average = ($sum/(count($timeValues) - 1));
|
||||
return ($average >= 180*24*60*60 ? 'yearly' :
|
||||
($average <= 24*60*60 ? 'daily' :
|
||||
($average <= 60*60 ? 'hourly' :
|
||||
($average <= 14*24*60*60 ? 'weekly' : 'monthly'))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link to a single page
|
||||
*
|
||||
* @param array $pageId Page ID
|
||||
* @return string Full URL of the page including host name (escaped)
|
||||
*/
|
||||
protected function getPageLink($pageId) {
|
||||
$conf = array(
|
||||
'parameter' => $pageId,
|
||||
'returnLast' => 'url',
|
||||
);
|
||||
$link = htmlspecialchars($this->cObj->typoLink('', $conf));
|
||||
return GeneralUtility::locationHeaderUrl($link);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use \TYPO3\CMS\Core\Utility\MathUtility;
|
||||
|
||||
/**
|
||||
* This class implements news sitemap
|
||||
* (http://www.google.com/support/webmasters/bin/answer.py?hl=en-nz&answer=42738)
|
||||
* for Google.
|
||||
*
|
||||
* The following URL parameters are expected:
|
||||
* - sitemap=news
|
||||
* - singlePid=<uid of the "single" tt_news view>
|
||||
* - pidList=<comma-separated list of storage pids>
|
||||
* All pids must be in the rootline of the current pid. The safest way is to call
|
||||
* this site map from the root page of the site:
|
||||
* http://example.com/?eID=dd_googlesitemap&sitemap=news&singlePid=100&pidList=101,102,115
|
||||
*
|
||||
* If you need to show news on different single view pages, make several sitemaps
|
||||
* (it is possible with Google).
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class TtNewsSitemapGenerator extends AbstractSitemapGenerator {
|
||||
|
||||
/**
|
||||
* List of storage pages where news items are located
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pidList = array();
|
||||
|
||||
/**
|
||||
* Indicates sitemap type
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isNewsSitemap;
|
||||
|
||||
/**
|
||||
* Single view page
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $singlePid;
|
||||
|
||||
/**
|
||||
* If true, try to get the single pid for a news item from its (first) category with fallback to $this->singlePid
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $useCategorySinglePid;
|
||||
|
||||
/**
|
||||
* Creates an instance of this class
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->isNewsSitemap = (GeneralUtility::_GET('type') === 'news');
|
||||
if ($this->isNewsSitemap) {
|
||||
$this->rendererClass = 'DmitryDulepov\\DdGooglesitemap\\Renderers\\NewsSitemapRenderer';
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$singlePid = intval(GeneralUtility::_GP('singlePid'));
|
||||
$this->singlePid = $singlePid && $this->isInRootline($singlePid) ? $singlePid : $GLOBALS['TSFE']->id;
|
||||
$this->useCategorySinglePid = (bool) GeneralUtility::_GP('useCategorySinglePid');
|
||||
|
||||
$this->validateAndcreatePageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates news site map.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function generateSitemapContent() {
|
||||
if (count($this->pidList) > 0) {
|
||||
$languageCondition = '';
|
||||
$language = GeneralUtility::_GP('L');
|
||||
if (MathUtility::canBeInterpretedAsInteger($language)) {
|
||||
$languageCondition = ' AND sys_language_uid=' . $language;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*',
|
||||
'tt_news', 'pid IN (' . implode(',', $this->pidList) . ')' .
|
||||
($this->isNewsSitemap ? ' AND crdate>=' . (time() - 48*60*60) : '') .
|
||||
$languageCondition .
|
||||
$this->cObj->enableFields('tt_news'), '', 'datetime DESC',
|
||||
$this->offset . ',' . $this->limit
|
||||
);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$rowCount = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
while (false !== ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
|
||||
$forceSinglePid = NULL;
|
||||
if ($row['category'] && $this->useCategorySinglePid) {
|
||||
$forceSinglePid = $this->getSinglePidFromCategory($row['uid']);
|
||||
}
|
||||
if (($url = $this->getNewsItemUrl($row, $forceSinglePid))) {
|
||||
echo $this->renderer->renderEntry($url, $row['title'], $row['datetime'],
|
||||
'', $row['keywords']);
|
||||
}
|
||||
}
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$GLOBALS['TYPO3_DB']->sql_free_result($res);
|
||||
|
||||
if ($rowCount === 0) {
|
||||
echo '<!-- It appears that there are no tt_news entries. If your ' .
|
||||
'news storage sysfolder is outside of the rootline, you may ' .
|
||||
'want to use the dd_googlesitemap.skipRootlineCheck=1 TS ' .
|
||||
'setup option. Beware: it is insecure and may cause certain ' .
|
||||
'undesired effects! Better move your news sysfolder ' .
|
||||
'inside the rootline! -->';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a pid for the single view from the category.
|
||||
*
|
||||
* @param int $newsId
|
||||
* @return int|null
|
||||
*/
|
||||
protected function getSinglePidFromCategory($newsId) {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$res = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
|
||||
'tt_news_cat.single_pid',
|
||||
'tt_news',
|
||||
'tt_news_cat_mm',
|
||||
'tt_news_cat',
|
||||
' AND tt_news_cat_mm.uid_local = ' . intval($newsId)
|
||||
);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$categoryRecord = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
|
||||
|
||||
return $categoryRecord['single_pid'] ?: NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link to the news item
|
||||
*
|
||||
* @param array $newsRow News item
|
||||
* @param int $forceSinglePid Single View page for this news item
|
||||
* @return string
|
||||
*/
|
||||
protected function getNewsItemUrl($newsRow, $forceSinglePid = NULL) {
|
||||
$link = '';
|
||||
if (is_string($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink']) && is_array($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink'])) {
|
||||
$cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
|
||||
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
|
||||
$cObj->start($newsRow, 'tt_news');
|
||||
$cObj->setCurrentVal($forceSinglePid ?: $this->singlePid);
|
||||
$link = $cObj->cObjGetSingle($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink'], $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink']);
|
||||
unset($cObj);
|
||||
}
|
||||
if ($link == '') {
|
||||
$conf = array(
|
||||
'additionalParams' => '&tx_ttnews[tt_news]=' . $newsRow['uid'],
|
||||
'forceAbsoluteUrl' => 1,
|
||||
'parameter' => $forceSinglePid ?: $this->singlePid,
|
||||
'returnLast' => 'url',
|
||||
'useCacheHash' => true,
|
||||
);
|
||||
$link = htmlspecialchars($this->cObj->typoLink('', $conf));
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that page list is in the rootline of the current page and excludes
|
||||
* pages that are outside of the rootline.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function validateAndcreatePageList() {
|
||||
// Get pages
|
||||
$pidList = GeneralUtility::intExplode(',', GeneralUtility::_GP('pidList'));
|
||||
// Check pages
|
||||
foreach ($pidList as $pid) {
|
||||
if ($pid && $this->isInRootline($pid)) {
|
||||
$this->pidList[$pid] = $pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if supplied page id and current page are in the same root line
|
||||
*
|
||||
* @param int $pid Page id to check
|
||||
* @return boolean true if page is in the root line
|
||||
*/
|
||||
protected function isInRootline($pid) {
|
||||
if (isset($GLOBALS['TSFE']->config['config']['tx_ddgooglesitemap_skipRootlineCheck'])) {
|
||||
$skipRootlineCheck = $GLOBALS['TSFE']->config['config']['tx_ddgooglesitemap_skipRootlineCheck'];
|
||||
}
|
||||
else {
|
||||
$skipRootlineCheck = $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['skipRootlineCheck'];
|
||||
}
|
||||
if ($skipRootlineCheck) {
|
||||
$result = true;
|
||||
}
|
||||
else {
|
||||
$result = false;
|
||||
$rootPid = intval($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['forceStartPid']);
|
||||
if ($rootPid == 0) {
|
||||
$rootPid = $GLOBALS['TSFE']->id;
|
||||
}
|
||||
$rootline = $GLOBALS['TSFE']->sys_page->getRootLine($pid);
|
||||
foreach ($rootline as $row) {
|
||||
if ($row['uid'] == $rootPid) {
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
140
typo3conf/ext/dd_googlesitemap/Classes/Hooks/TceMain.php
Normal file
140
typo3conf/ext/dd_googlesitemap/Classes/Hooks/TceMain.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2008-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Hooks;
|
||||
|
||||
use \TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use \TYPO3\CMS\Core\Utility\MathUtility;
|
||||
|
||||
/**
|
||||
* Page and content manipulation watch.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class TceMain {
|
||||
|
||||
/**
|
||||
* If > 1 than we are in the recursive call to ourselves and we do not do anything
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lock = 0;
|
||||
|
||||
/**
|
||||
* Maximum number of timestamps to save
|
||||
*
|
||||
*/
|
||||
const MAX_ENTRIES = 5;
|
||||
|
||||
/** @var int[] */
|
||||
static protected $recordedPages = array();
|
||||
|
||||
/**
|
||||
* Hooks to data change procedure to watch modified data. This hook is called
|
||||
* after data is written to the database, so all paths are modified paths.
|
||||
*
|
||||
* @param string $status Record status (new or update)
|
||||
* @param string $table Table name
|
||||
* @param int $id Record ID
|
||||
* @param array $fieldArray Modified fields
|
||||
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $pObj Reference to TCEmain
|
||||
*/
|
||||
public function processDatamap_afterDatabaseOperations(/** @noinspection PhpUnusedParameterInspection */ $status, $table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
|
||||
// Only for LIVE records!
|
||||
if ($pObj->BE_USER->workspace == 0 && !$this->lock) {
|
||||
$this->lock++;
|
||||
$this->recordPageChange($table, $id, $fieldArray, $pObj);
|
||||
$this->lock--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records page change time in our own field
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @param int $id ID of the record
|
||||
* @param array $fieldArray Field array
|
||||
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $pObj Reference to TCEmain
|
||||
* @return void
|
||||
*/
|
||||
protected function recordPageChange($table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
|
||||
if (($pid = $this->getPid($table, $id, $fieldArray, $pObj)) && !isset(self::$recordedPages[$pid])) {
|
||||
self::$recordedPages[$pid] = 1;
|
||||
|
||||
$record = BackendUtility::getRecord('pages', $pid, 'tx_ddgooglesitemap_lastmod');
|
||||
$elements = $record['tx_ddgooglesitemap_lastmod'] == '' ? array() : GeneralUtility::trimExplode(',', $record['tx_ddgooglesitemap_lastmod']);
|
||||
$time = time();
|
||||
// We must check if this time stamp is already in the list. This
|
||||
// happens with many independent updates of the page during a
|
||||
// single TCEmain action
|
||||
if (!in_array($time, $elements)) {
|
||||
$elements[] = $time;
|
||||
if (count($elements) > self::MAX_ENTRIES) {
|
||||
$elements = array_slice($elements, -self::MAX_ENTRIES);
|
||||
}
|
||||
|
||||
$datamap = array(
|
||||
'pages' => array(
|
||||
$pid => array(
|
||||
'tx_ddgooglesitemap_lastmod' => implode(',', $elements),
|
||||
),
|
||||
),
|
||||
);
|
||||
$tce = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
|
||||
/* @var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
|
||||
$tce->start($datamap, NULL);
|
||||
$tce->enableLogging = FALSE;
|
||||
$tce->process_datamap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains page id from the arguments
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @param int $id ID of the record
|
||||
* @param array $fieldArray Field array
|
||||
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $pObj Reference to TCEmain
|
||||
* @return int
|
||||
*/
|
||||
protected function getPid($table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
|
||||
if (!MathUtility::canBeInterpretedAsInteger($id)) {
|
||||
$id = $pObj->substNEWwithIDs[$id];
|
||||
}
|
||||
if ($table !== 'pages') {
|
||||
if (isset($fieldArray['pid']) && MathUtility::canBeInterpretedAsInteger($fieldArray['pid']) && $fieldArray['pid'] >= 0) {
|
||||
$id = $fieldArray['pid'];
|
||||
}
|
||||
else {
|
||||
$record = BackendUtility::getRecord($table, $id, 'pid');
|
||||
$id = $record['pid'];
|
||||
}
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2009-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Renderers;
|
||||
|
||||
/**
|
||||
* This class contains an abstract renderer for sitemaps.
|
||||
*
|
||||
* NOTE: interface is internal and it is not stable. Any XCLASS is not guarantied
|
||||
* to work!
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
abstract class AbstractSitemapRenderer {
|
||||
|
||||
/**
|
||||
* Creates start XML tags (including XML prologue) for the sitemap.
|
||||
*
|
||||
* @return string Start tags
|
||||
*/
|
||||
abstract public function getStartTags();
|
||||
|
||||
/**
|
||||
* Renders one single entry according to the format of this sitemap.
|
||||
*
|
||||
* @param string $url URL of the entry
|
||||
* @param string $title Title of the entry
|
||||
* @param int $lastModification News publication time (Unix timestamp)
|
||||
* @param string $changeFrequency Unused for news
|
||||
* @param string $keywords Keywords for this entry
|
||||
* @param mixed $priority Priority (numeric, 1-10, if passed)
|
||||
* @return string Generated entry content
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::renderEntry()
|
||||
*/
|
||||
abstract public function renderEntry($url, $title, $lastModification = 0, $changeFrequency = '', $keywords = '', $priority = '');
|
||||
|
||||
/**
|
||||
* Creates end XML tags for this sitemap.
|
||||
*
|
||||
* @return string End XML tags
|
||||
*/
|
||||
abstract public function getEndTags();
|
||||
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_abstract_renderer.php']) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_abstract_renderer.php']);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2009-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Renderers;
|
||||
|
||||
/**
|
||||
* This class contains a renderer for the 'news' sitemap.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class NewsSitemapRenderer extends AbstractSitemapRenderer {
|
||||
|
||||
/**
|
||||
* Contains google news site name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sitename;
|
||||
|
||||
/**
|
||||
* Creates an instance of this class
|
||||
*/
|
||||
public function __construct() {
|
||||
if ($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['google_news_site_name']) {
|
||||
$this->sitename = $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['google_news_site_name'];
|
||||
}
|
||||
else {
|
||||
$this->sitename = $GLOBALS['TSFE']->tmpl->setup['sitetitle'];
|
||||
}
|
||||
$this->sitename = htmlspecialchars($this->sitename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates end tags for this sitemap.
|
||||
*
|
||||
* @return string End XML tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getEndTags()
|
||||
*/
|
||||
public function getEndTags() {
|
||||
return '</urlset>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates start tags for this sitemap.
|
||||
*
|
||||
* @return string Start tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getStartTags()
|
||||
*/
|
||||
public function getStartTags() {
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . chr(10) .
|
||||
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" ' .
|
||||
'xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"' .
|
||||
'>' . chr(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single entry as a news entry.
|
||||
*
|
||||
* @param string $url URL of the entry
|
||||
* @param string $title Title of the entry
|
||||
* @param int $lastModification News publication time (Unix timestamp)
|
||||
* @param string $changeFrequency Unused for news
|
||||
* @param string $keywords Keywords for this entry
|
||||
* @param mixed $priority Priority (numeric, 1-10, if passed)
|
||||
* @return string Generated entry content
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::renderEntry()
|
||||
*/
|
||||
public function renderEntry($url, $title, $lastModification = 0, $changeFrequency = '', $keywords = '', $priority = '') {
|
||||
$content = '<url>';
|
||||
$content .= '<loc>' . $url . '</loc>';
|
||||
// News must have a publication date, so we put this unconditionally!
|
||||
$content .= '<news:news>';
|
||||
$content .= '<news:publication>';
|
||||
$content .= '<news:name>' . $this->sitename . '</news:name>';
|
||||
$content .= '<news:language>' . htmlspecialchars($GLOBALS['TSFE']->lang) . '</news:language>';
|
||||
$content .= '</news:publication>';
|
||||
$content .= '<news:publication_date>' . date('c', $lastModification) . '</news:publication_date>';
|
||||
$content .= '<news:title>' . htmlspecialchars($title) . '</news:title>';
|
||||
if ($keywords) {
|
||||
$content .= '<news:keywords>' . htmlspecialchars($keywords) . '</news:keywords>';
|
||||
}
|
||||
$content .= '</news:news>';
|
||||
$content .= '</url>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_news_renderer.php']) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_news_renderer.php']);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2009-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Renderers;
|
||||
|
||||
/**
|
||||
* This class contains a renderer for the 'normal' (not 'news') sitemap.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class StandardSitemapRenderer extends AbstractSitemapRenderer {
|
||||
|
||||
/**
|
||||
* Creates end tags for this sitemap.
|
||||
*
|
||||
* @return string End XML tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getEndTags()
|
||||
*/
|
||||
public function getEndTags() {
|
||||
return '</urlset>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates start tags for this sitemap.
|
||||
*
|
||||
* @return string Start tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getStartTags()
|
||||
*/
|
||||
public function getStartTags() {
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . chr(10) .
|
||||
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . chr(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single entry as a normal sitemap entry.
|
||||
*
|
||||
* @param string $url URL of the entry
|
||||
* @param string $title Title of the entry
|
||||
* @param int $lastModification News publication time (Unix timestamp)
|
||||
* @param string $changeFrequency Unused for news
|
||||
* @param string $keywords Keywords for this entry
|
||||
* @param mixed $priority Priority (numeric, 1-10, if passed)
|
||||
* @return string Generated entry content
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::renderEntry()
|
||||
*/
|
||||
public function renderEntry($url, $title, $lastModification = 0, $changeFrequency = '', $keywords = '', $priority = '') {
|
||||
$content = '<url>';
|
||||
$content .= '<loc>' . $url . '</loc>';
|
||||
if ($lastModification) {
|
||||
$content .= '<lastmod>' . date('c', $lastModification) . '</lastmod>';
|
||||
}
|
||||
if ($changeFrequency) {
|
||||
$content .= '<changefreq>' . $changeFrequency . '</changefreq>';
|
||||
}
|
||||
if ($priority != '') {
|
||||
$content .= '<priority>' . sprintf('%0.1F', $priority/10) . '</priority>';
|
||||
}
|
||||
$content .= '</url>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_normal_renderer.php']) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_normal_renderer.php']);
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2013-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Scheduler;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class provides information about additional fields for the scheduler
|
||||
* task of this extension. Additional fields are:
|
||||
* - the URL of the eID script (users can use different parameters for the script!)
|
||||
* - index file path (users will submit that to Google)
|
||||
* - maximum number of URLs in the sitemap (to prevent out of memory errors)
|
||||
*
|
||||
* WARNING! Due to incompatible TYPO3 6.2 changes this class now shows PHP errors
|
||||
* in TYPO3 4.5 and TYPO3 6.2 in the PhpStorm. These errors however do not happen
|
||||
* at runtime.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
*/
|
||||
class AdditionalFieldsProvider implements \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface {
|
||||
|
||||
/**
|
||||
* Gets additional fields to render in the form to add/edit a task
|
||||
*
|
||||
* @param array $taskInfo Values of the fields from the add/edit task form
|
||||
* @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task The task object being edited. Null when adding a task!
|
||||
* @param \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule Reference to the scheduler backend module
|
||||
* @return array A two dimensional array, array('Identifier' => array('fieldId' => array('code' => '', 'label' => '', 'cshKey' => '', 'cshLabel' => ''))
|
||||
*/
|
||||
public function getAdditionalFields(array &$taskInfo, $task, \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule) {
|
||||
/** @var \DmitryDulepov\DdGooglesitemap\Scheduler\Task $task */
|
||||
$additionalFields = array();
|
||||
|
||||
if (!$task) {
|
||||
$url = GeneralUtility::locationHeaderUrl('/index.php?eID=dd_googlesitemap');
|
||||
$task = GeneralUtility::makeInstance('DmitryDulepov\\DdGooglesitemap\\Scheduler\\Task');
|
||||
}
|
||||
else {
|
||||
$url = $task->getEIdScriptUrl();
|
||||
}
|
||||
$indexFilePath = $task->getIndexFilePath();
|
||||
$maxUrlsPerSitemap = $task->getMaxUrlsPerSitemap();
|
||||
|
||||
$additionalFields['eIdUrl'] = array(
|
||||
'code' => '<textarea style="width:350px;height:200px" name="tx_scheduler[eIdUrl]" wrap="off">' . htmlspecialchars($url) . '</textarea>',
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.eIDFieldLabel',
|
||||
'cshKey' => '',
|
||||
'cshLabel' => ''
|
||||
);
|
||||
$additionalFields['indexFilePath'] = array(
|
||||
'code' => '<input class="wide" type="text" name="tx_scheduler[indexFilePath]" value="' . htmlspecialchars($indexFilePath) . '" />',
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.indexFieldLabel',
|
||||
'cshKey' => '',
|
||||
'cshLabel' => ''
|
||||
);
|
||||
$additionalFields['maxUrlsPerSitemap'] = array(
|
||||
'code' => '<input type="text" name="tx_scheduler[maxUrlsPerSitemap]" value="' . $maxUrlsPerSitemap . '" />',
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.maxUrlsPerSitemapLabel',
|
||||
'cshKey' => '',
|
||||
'cshLabel' => ''
|
||||
);
|
||||
|
||||
return $additionalFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the additional fields' values
|
||||
*
|
||||
* @param array $submittedData An array containing the data submitted by the add/edit task form
|
||||
* @param \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule Reference to the scheduler backend module
|
||||
* @return boolean TRUE if validation was ok (or selected class is not relevant), FALSE otherwise
|
||||
*/
|
||||
public function validateAdditionalFields(array &$submittedData, \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule) {
|
||||
$errors = array();
|
||||
|
||||
$this->validateEIdUrl($submittedData, $errors);
|
||||
$this->validateMaxUrlsPerSitemap($submittedData, $errors);
|
||||
$this->validateIndexFilePath($submittedData, $errors);
|
||||
|
||||
foreach ($errors as $error) {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$error = $GLOBALS['LANG']->sL('LLL:EXT:dd_googlesitemap/locallang.xml:' . $error);
|
||||
$this->addErrorMessage($error);
|
||||
}
|
||||
|
||||
return count($errors) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of saving the additional fields' values in the task's object
|
||||
*
|
||||
* @param array $submittedData An array containing the data submitted by the add/edit task form
|
||||
* @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task Reference to the scheduler backend module
|
||||
* @return void
|
||||
*/
|
||||
public function saveAdditionalFields(array $submittedData, \TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
|
||||
/** @var \DmitryDulepov\DdGooglesitemap\Scheduler\Task $task */
|
||||
$task->setEIdScriptUrl($submittedData['eIdUrl']);
|
||||
$task->setMaxUrlsPerSitemap($submittedData['maxUrlsPerSitemap']);
|
||||
$task->setIndexFilePath($submittedData['indexFilePath']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a error message as a flash message.
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
protected function addErrorMessage($message) {
|
||||
$flashMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
|
||||
$message, '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
|
||||
);
|
||||
/** @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
|
||||
$flashMessageService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessageService');
|
||||
/** @var \TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService */
|
||||
$flashMessageService->getMessageQueueByIdentifier()->enqueue($flashMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the number of urls per sitemap.
|
||||
*
|
||||
* @param array $submittedData
|
||||
* @param array $errors
|
||||
* @return void
|
||||
*/
|
||||
protected function validateMaxUrlsPerSitemap(array &$submittedData, array &$errors) {
|
||||
$submittedData['maxUrlsPerSitemap'] = intval($submittedData['maxUrlsPerSitemap']);
|
||||
if ($submittedData['maxUrlsPerSitemap'] <= 0) {
|
||||
$errors[] = 'scheduler.error.badNumberOfUrls';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates index file path.
|
||||
*
|
||||
* @param array $submittedData
|
||||
* @param array $errors
|
||||
* @return void
|
||||
*/
|
||||
protected function validateIndexFilePath(array &$submittedData, array &$errors) {
|
||||
if (GeneralUtility::isAbsPath($submittedData['indexFilePath'])) {
|
||||
$errors[] = 'scheduler.error.badIndexFilePath';
|
||||
}
|
||||
else {
|
||||
$testPath = GeneralUtility::getFileAbsFileName($submittedData['indexFilePath'], TRUE);
|
||||
if (!file_exists($testPath)) {
|
||||
if (!@touch($testPath)) {
|
||||
$errors[] = 'scheduler.error.badIndexFilePath';
|
||||
}
|
||||
else {
|
||||
unlink($testPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Valies the URL of the eID script.
|
||||
*
|
||||
* @param array $submittedData
|
||||
* @param array $errors
|
||||
*/
|
||||
protected function validateEIdUrl(array &$submittedData, array &$errors) {
|
||||
foreach (GeneralUtility::trimExplode(chr(10), $submittedData['eIdUrl']) as $url) {
|
||||
if (FALSE !== ($urlParts = parse_url($url))) {
|
||||
if (!$urlParts['host']) {
|
||||
$errors[] = 'scheduler.error.missingHost';
|
||||
}
|
||||
else {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
list($count) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('COUNT(*) AS counter', 'sys_domain',
|
||||
'domainName=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($urlParts['host'], 'sys_domain')
|
||||
);
|
||||
if ($count['counter'] == 0) {
|
||||
$errors[] = 'scheduler.error.missingHost';
|
||||
}
|
||||
}
|
||||
if (!preg_match('/(?:^|&)eID=dd_googlesitemap/', $urlParts['query'])) {
|
||||
$errors[] = 'scheduler.error.badPath';
|
||||
}
|
||||
if (preg_match('/(?:^|&)(?:offset|limit)=/', $urlParts['query'])) {
|
||||
$errors[] = 'scheduler.error.badParameters';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
300
typo3conf/ext/dd_googlesitemap/Classes/Scheduler/Task.php
Normal file
300
typo3conf/ext/dd_googlesitemap/Classes/Scheduler/Task.php
Normal file
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2013 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Scheduler;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class provides a scheduler task to create sitemap index as required
|
||||
* by the Google sitemap protocol.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @see http://support.google.com/webmasters/bin/answer.py?hl=en&answer=71453
|
||||
*/
|
||||
class Task extends \TYPO3\CMS\Scheduler\Task\AbstractTask {
|
||||
|
||||
const DEFAULT_FILE_PATH = 'typo3temp/dd_googlesitemap';
|
||||
|
||||
/** @var string */
|
||||
private $baseUrl;
|
||||
|
||||
/** @var string */
|
||||
protected $eIdScriptUrl;
|
||||
|
||||
/** @var string */
|
||||
protected $indexFilePath;
|
||||
|
||||
/** @var int */
|
||||
protected $maxUrlsPerSitemap = 50000;
|
||||
|
||||
/** @var string */
|
||||
private $sitemapFileFormat;
|
||||
|
||||
/** @var int */
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* Creates the instance of the class. This call initializes the index file
|
||||
* path to the random value. After the task is configured, the user may
|
||||
* change the file and the file name will be serialized with the task and
|
||||
* used later.
|
||||
*
|
||||
* @see __sleep
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->indexFilePath = self::DEFAULT_FILE_PATH . '/' . GeneralUtility::getRandomHexString(24) . '.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs some variables after the object is unserialized.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup() {
|
||||
$this->buildSitemapFileFormat();
|
||||
$this->buildBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main method that is called when a task is executed
|
||||
* It MUST be implemented by all classes inheriting from this one
|
||||
* Note that there is no error handling, errors and failures are expected
|
||||
* to be handled and logged by the client implementations.
|
||||
* Should return true on successful execution, false on error.
|
||||
*
|
||||
* @return boolean Returns true on successful execution, false on error
|
||||
*/
|
||||
public function execute() {
|
||||
$indexFilePathTemp = PATH_site . $this->indexFilePath . '.tmp';
|
||||
$indexFile = fopen($indexFilePathTemp, 'wt');
|
||||
fwrite($indexFile, '<?xml version="1.0" encoding="UTF-8"?>' . chr(10));
|
||||
fwrite($indexFile, '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . chr(10));
|
||||
|
||||
$eIDscripts = GeneralUtility::trimExplode(chr(10), $this->eIdScriptUrl);
|
||||
$eIdIndex = 1;
|
||||
foreach ($eIDscripts as $eIdScriptUrl) {
|
||||
$this->offset = 0;
|
||||
$currentFileNumber = 1;
|
||||
$lastFileHash = '';
|
||||
do {
|
||||
$sitemapFileName = sprintf($this->sitemapFileFormat, $eIdIndex, $currentFileNumber++);
|
||||
$this->buildSitemap($eIdScriptUrl, $sitemapFileName);
|
||||
|
||||
$isSitemapEmpty = $this->isSitemapEmpty($sitemapFileName);
|
||||
$currentFileHash = $isSitemapEmpty ? -1 : md5_file(PATH_site . $sitemapFileName);
|
||||
$stopLoop = $isSitemapEmpty || ($currentFileHash == $lastFileHash);
|
||||
|
||||
if ($stopLoop) {
|
||||
@unlink(PATH_site . $sitemapFileName);
|
||||
}
|
||||
else {
|
||||
fwrite($indexFile, '<sitemap><loc>' . htmlspecialchars($this->makeSitemapUrl($sitemapFileName)) . '</loc></sitemap>' . chr(10));
|
||||
$lastFileHash = $currentFileHash;
|
||||
}
|
||||
} while (!$stopLoop);
|
||||
$eIdIndex++;
|
||||
}
|
||||
|
||||
fwrite($indexFile, '</sitemapindex>' . chr(10));
|
||||
fclose($indexFile);
|
||||
|
||||
@unlink(PATH_site . $this->indexFilePath);
|
||||
rename($indexFilePathTemp, PATH_site . $this->indexFilePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is designed to return some additional information about the task,
|
||||
* that may help to set it apart from other tasks from the same class
|
||||
* This additional information is used - for example - in the Scheduler's BE module
|
||||
* This method should be implemented in most task classes
|
||||
*
|
||||
* @return string Information to display
|
||||
*/
|
||||
public function getAdditionalInformation() {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$format = $GLOBALS['LANG']->sL('LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.extra_info');
|
||||
return sprintf($format, $this->getIndexFileUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the url of the eID script. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @return string
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function getEIdScriptUrl() {
|
||||
return $this->eIdScriptUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index file path. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @return string
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function getIndexFilePath() {
|
||||
return $this->indexFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the number of urls per sitemap. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @return int
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function getMaxUrlsPerSitemap() {
|
||||
return $this->maxUrlsPerSitemap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URl of the eID script. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @param $url
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function setEIdScriptUrl($url) {
|
||||
$this->eIdScriptUrl = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL of the eID script. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @param string $path
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function setIndexFilePath($path) {
|
||||
$this->indexFilePath = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of URLs per sitemap. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @param int $maxUrlsPerSitemap
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function setMaxUrlsPerSitemap($maxUrlsPerSitemap) {
|
||||
$this->maxUrlsPerSitemap = $maxUrlsPerSitemap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a base url for sitemaps.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function buildBaseUrl() {
|
||||
$urlParts = parse_url($this->eIdScriptUrl);
|
||||
$this->baseUrl = $urlParts['scheme'] . '://';
|
||||
if ($urlParts['user']) {
|
||||
$this->baseUrl .= $urlParts['user'];
|
||||
if ($urlParts['pass']) {
|
||||
$this->baseUrl .= ':' . $urlParts['pass'];
|
||||
}
|
||||
$this->baseUrl .= '@';
|
||||
}
|
||||
$this->baseUrl .= $urlParts['host'];
|
||||
if ($urlParts['port']) {
|
||||
$this->baseUrl .= ':' . $urlParts['port'];
|
||||
}
|
||||
$this->baseUrl .= '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the sitemap.
|
||||
*
|
||||
* @param string $eIdScriptUrl
|
||||
* @param string $sitemapFileName
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
protected function buildSitemap($eIdScriptUrl, $sitemapFileName) {
|
||||
$url = $eIdScriptUrl . sprintf('&offset=%d&limit=%d', $this->offset, $this->maxUrlsPerSitemap);
|
||||
|
||||
$content = GeneralUtility::getURL($url);
|
||||
if ($content) {
|
||||
file_put_contents(PATH_site . $sitemapFileName, $content);
|
||||
$this->offset += $this->maxUrlsPerSitemap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the format string for the sitemap files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function buildSitemapFileFormat() {
|
||||
$fileParts = pathinfo($this->indexFilePath);
|
||||
$this->sitemapFileFormat = $fileParts['dirname'] . '/' . $fileParts['filename'] . '_sitemap_%05d_%05d.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index file url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getIndexFileUrl() {
|
||||
return $this->baseUrl . $this->indexFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current sitemap has no entries. The function reads a chunk
|
||||
* of the file, which is large enough to have a '<url>' token in it and
|
||||
* examines the chunk. If the token is not found, than the sitemap is either
|
||||
* empty or corrupt.
|
||||
*
|
||||
* @param string $sitemapFileName
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSitemapEmpty($sitemapFileName) {
|
||||
$result = TRUE;
|
||||
|
||||
$fileDescriptor = @fopen(PATH_site . $sitemapFileName, 'rt');
|
||||
if ($fileDescriptor) {
|
||||
$chunkSizeToCheck = 10240;
|
||||
$testString = fread($fileDescriptor, $chunkSizeToCheck);
|
||||
fclose($fileDescriptor);
|
||||
$result = (strpos($testString, '<url>') === FALSE);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a url to the sitemap.
|
||||
*
|
||||
* @param string $siteMapPath
|
||||
* @return string
|
||||
*/
|
||||
protected function makeSitemapUrl($siteMapPath) {
|
||||
return $this->baseUrl . $siteMapPath;
|
||||
}
|
||||
}
|
||||
22
typo3conf/ext/dd_googlesitemap/README.md
Normal file
22
typo3conf/ext/dd_googlesitemap/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
Google sitemaps for TYPO3
|
||||
======================
|
||||
|
||||
This is a "dd_googlesitemap" TYPO3 extension. You will need a TYPO3 CMS to run it.
|
||||
|
||||
What does it do?
|
||||
----------------
|
||||
This extension adds sitemaps for pages and tt_news items. Typically you add the result to Google like http://example.com/index.php?eID=dd_googlesitemap.
|
||||
|
||||
Make sure to read the manual in the doc/ directory before asking questions or writing bug reports. Anything, which is explained in the manual, will be silently closed without answering.
|
||||
|
||||
What it does not do?
|
||||
--------------------
|
||||
Many things. It is deliberately not a "all-purpose solution". It is created to be fast and efficient. It only contains sitemaps for pages and tt_news and there are no plans to change that or do any sophisticated filtering, etc. You still can ask though :)
|
||||
|
||||
Repository
|
||||
----------
|
||||
Main repository is at https://github.com/dmitryd/typo3_dd_googlesitemap.
|
||||
|
||||
Contact
|
||||
-------
|
||||
E-mail: dmitry.dulepov@gmail.com
|
||||
31
typo3conf/ext/dd_googlesitemap/composer.json
Normal file
31
typo3conf/ext/dd_googlesitemap/composer.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "dmitryd/typo3-dd-googlesitemap",
|
||||
"type": "typo3-cms-extension",
|
||||
"description": "Google sitemaps for TYPO3",
|
||||
"homepage": "https://github.com/dmitryd/typo3-dd_googlesitemap ",
|
||||
"version": "2.0.5",
|
||||
"license": "LGPL-3.0+",
|
||||
"keywords": [
|
||||
"TYPO3",
|
||||
"CMS",
|
||||
"Google",
|
||||
"typo3",
|
||||
"sitemap"
|
||||
],
|
||||
"require": {
|
||||
"typo3/cms-core": ">=6.2.0,<8.0",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DmitryDulepov\\DdGooglesitemap\\": "Classes"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dmitry Dulepov",
|
||||
"email": "dmitry.dulepov@gmail.com",
|
||||
"homepage": "http://www.dmitry-dulepov.com/"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
typo3conf/ext/dd_googlesitemap/doc/manual.sxw
Normal file
BIN
typo3conf/ext/dd_googlesitemap/doc/manual.sxw
Normal file
Binary file not shown.
39
typo3conf/ext/dd_googlesitemap/ext_emconf.php
Normal file
39
typo3conf/ext/dd_googlesitemap/ext_emconf.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/***************************************************************
|
||||
* Extension Manager/Repository config file for ext "dd_googlesitemap".
|
||||
*
|
||||
* Auto generated 19-02-2016 08:08
|
||||
*
|
||||
* Manual updates:
|
||||
* Only the data in the array - everything else is removed by next
|
||||
* writing. "version" and "dependencies" must not be touched!
|
||||
***************************************************************/
|
||||
|
||||
$EM_CONF[$_EXTKEY] = array (
|
||||
'title' => 'Google sitemap',
|
||||
'description' => 'High performance Google sitemap implementation that avoids typical errors by other similar extensions',
|
||||
'category' => 'fe',
|
||||
'version' => '2.0.5',
|
||||
'state' => 'stable',
|
||||
'uploadfolder' => true,
|
||||
'createDirs' => 'typo3temp/dd_googlesitemap',
|
||||
'clearcacheonload' => true,
|
||||
'author' => 'Dmitry Dulepov',
|
||||
'author_email' => 'dmitry.dulepov@gmail.com',
|
||||
'author_company' => 'SIA "ACCIO"',
|
||||
'constraints' =>
|
||||
array (
|
||||
'depends' =>
|
||||
array (
|
||||
'typo3' => '6.2.0-7.6.999',
|
||||
),
|
||||
'conflicts' =>
|
||||
array (
|
||||
),
|
||||
'suggests' =>
|
||||
array (
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
BIN
typo3conf/ext/dd_googlesitemap/ext_icon.gif
Normal file
BIN
typo3conf/ext/dd_googlesitemap/ext_icon.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
23
typo3conf/ext/dd_googlesitemap/ext_localconf.php
Normal file
23
typo3conf/ext/dd_googlesitemap/ext_localconf.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
if (!defined('TYPO3_MODE')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// eID
|
||||
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['dd_googlesitemap'] = 'EXT:dd_googlesitemap/Classes/Generator/EntryPoint.php';
|
||||
|
||||
if (TYPO3_MODE == 'BE') {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['dd_googlesitemap'] = 'DmitryDulepov\\DdGooglesitemap\\Hooks\\TceMain';
|
||||
}
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks']['DmitryDulepov\\DdGooglesitemap\\Scheduler\\Task'] = array(
|
||||
'extension' => 'dd_googlesitemap',
|
||||
'title' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.title',
|
||||
'description' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.description',
|
||||
'additionalFields' => 'DmitryDulepov\\DdGooglesitemap\\Scheduler\\AdditionalFieldsProvider'
|
||||
);
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['sitemap']['pages'] = 'DmitryDulepov\\DdGooglesitemap\\Generator\\PagesSitemapGenerator->main';
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['sitemap']['tt_news'] = 'DmitryDulepov\\DdGooglesitemap\\Generator\\TtNewsSitemapGenerator->main';
|
||||
|
||||
?>
|
||||
39
typo3conf/ext/dd_googlesitemap/ext_tables.php
Normal file
39
typo3conf/ext/dd_googlesitemap/ext_tables.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
$tempColumns = Array (
|
||||
'tx_ddgooglesitemap_lastmod' => Array (
|
||||
'exclude' => 1,
|
||||
'label' => '',
|
||||
'config' => Array (
|
||||
'type' => 'passthrough',
|
||||
)
|
||||
),
|
||||
'tx_ddgooglesitemap_priority' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority',
|
||||
'displayCond' => 'FIELD:no_search:=:0',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'renderType' => 'selectSingle',
|
||||
'items' => array(
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.0', 0),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.1', 1),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.2', 2),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.3', 3),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.4', 4),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.5', 5),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.6', 6),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.7', 7),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.8', 8),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.9', 9),
|
||||
array('LLL:EXT:dd_googlesitemap/locallang.xml:pages.tx_ddgooglesitemap_priority.10', 10),
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages', $tempColumns);
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette('pages', 'miscellaneous', 'tx_ddgooglesitemap_priority');
|
||||
|
||||
unset($tempColumn);
|
||||
7
typo3conf/ext/dd_googlesitemap/ext_tables.sql
Normal file
7
typo3conf/ext/dd_googlesitemap/ext_tables.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Table structure for table 'pages'
|
||||
#
|
||||
CREATE TABLE pages (
|
||||
tx_ddgooglesitemap_lastmod varchar(255) DEFAULT '' NOT NULL,
|
||||
tx_ddgooglesitemap_priority int(3) DEFAULT '5' NOT NULL
|
||||
);
|
||||
6
typo3conf/ext/dd_googlesitemap/ext_typoscript_setup.txt
Normal file
6
typo3conf/ext/dd_googlesitemap/ext_typoscript_setup.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
tx_ddgooglesitemap {
|
||||
skipRootlineCheck = 0
|
||||
forceStartPid = 0
|
||||
# You can exclude more page types if you want but make sure to provide a complete list here!
|
||||
# excludePageType = 0,3,4,5,6,7,199,254,255
|
||||
}
|
||||
34
typo3conf/ext/dd_googlesitemap/locallang.xml
Normal file
34
typo3conf/ext/dd_googlesitemap/locallang.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<T3locallang>
|
||||
<meta type="array">
|
||||
<type>database</type>
|
||||
<description>Language labels for database tables/fields belonging to extension 'dd_googlesitemap'</description>
|
||||
</meta>
|
||||
<data type="array">
|
||||
<languageKey index="default" type="array">
|
||||
<label index="pages.tx_ddgooglesitemap_priority">Sitemap priority:</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.0">0.0 (lowest)</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.1">0.1</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.2">0.2</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.3">0.3</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.4">0.4</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.5">0.5 (standard)</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.6">0.6</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.7">0.7</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.8">0.8</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.9">0.9</label>
|
||||
<label index="pages.tx_ddgooglesitemap_priority.10">1.0 (highest)</label>
|
||||
<label index="scheduler.title">Generate offline sitemap</label>
|
||||
<label index="scheduler.description">Generates offline index file and sitemaps</label>
|
||||
<label index="scheduler.eIDFieldLabel">eID script URLs (one per line):</label>
|
||||
<label index="scheduler.indexFieldLabel">Index file path:</label>
|
||||
<label index="scheduler.maxUrlsPerSitemapLabel">URLs per sitemap:</label>
|
||||
<label index="scheduler.error.missingHost">Host is missing or does not match any of TYPO3 hosts from the installation.</label>
|
||||
<label index="scheduler.error.badPath">This task can only fetch scripts from dd_googlesitemap, not other URLs.</label>
|
||||
<label index="scheduler.error.badParameters">'offset' and 'limit' parameters may not appear in the URL.</label>
|
||||
<label index="scheduler.error.badIndexFilePath">Index file path must be relative to the site's main directory. The referenced directory must exist (the default directory is created when the extension is installed).</label>
|
||||
<label index="scheduler.error.badNumberOfUrls">Number of URLs must be positive.</label>
|
||||
<label index="scheduler.extra_info">Index file: `%1$s`</label>
|
||||
</languageKey>
|
||||
</data>
|
||||
</T3locallang>
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
namespace Ifabrik\IfAccessButtons\Controller;
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2016 Marco Kuprat <mk@internetfabrik.de>, Internetfabrik GmbH
|
||||
*
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
|
||||
|
||||
/**
|
||||
* AccessibilityButtonsController
|
||||
*/
|
||||
class AccessibilityButtonsController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
|
||||
|
||||
/**
|
||||
* accessibilityButtonsRepository
|
||||
*
|
||||
* @var \Ifabrik\IfAccessButtons\Domain\Repository\AccessibilityButtonsRepository
|
||||
* @inject
|
||||
*/
|
||||
protected $accessibilityButtonsRepository = NULL;
|
||||
|
||||
/**
|
||||
* action show
|
||||
*
|
||||
* @param \Ifabrik\IfAccessButtons\Domain\Model\AccessibilityButtons $accessibilityButtons
|
||||
* @return void
|
||||
*/
|
||||
public function showAction(\Ifabrik\IfAccessButtons\Domain\Model\AccessibilityButtons $accessibilityButtons = NULL) {
|
||||
|
||||
$sessiondata = $GLOBALS ["TSFE"]->fe_user->getKey ( 'ses', 'accessibility' );
|
||||
|
||||
if (is_array($sessiondata)) {
|
||||
if (!array_key_exists('kontrast', $sessiondata) || $sessiondata['kontrast'] == 0) {
|
||||
$accessibilityButtons['contrast_title'] = 'contrast_on';
|
||||
} else {
|
||||
$accessibilityButtons['contrast_title'] = 'contrast_off';
|
||||
}
|
||||
|
||||
if (!array_key_exists('schriftgroesse', $sessiondata) || $sessiondata['schriftgroesse'] == 0) {
|
||||
$accessibilityButtons['fontsize_title'] = 'fonts_larger';
|
||||
} else {
|
||||
$accessibilityButtons['fontsize_title'] = 'fonts_normal';
|
||||
}
|
||||
} else {
|
||||
$accessibilityButtons['contrast_title'] = 'contrast_on';
|
||||
$accessibilityButtons['fontsize_title'] = 'fonts_normal';
|
||||
}
|
||||
|
||||
$this->view->assign('accessibilityButtons', $accessibilityButtons);
|
||||
}
|
||||
|
||||
/**
|
||||
* action ajax
|
||||
*/
|
||||
public function ajaxAction() {
|
||||
$data = array();
|
||||
|
||||
$sessiondata = $GLOBALS ["TSFE"]->fe_user->getKey ( 'ses', 'accessibility' );
|
||||
|
||||
if (! is_array($sessiondata)) {
|
||||
$sessiondata = array();
|
||||
}
|
||||
|
||||
$args = $this->request->getArguments();
|
||||
|
||||
if (array_key_exists('btn', $args)) {
|
||||
if ($args['btn'] == 'kontrast') {
|
||||
if (!array_key_exists('kontrast', $sessiondata) || $sessiondata['kontrast'] == 0) {
|
||||
$sesKontrast = 1;
|
||||
} else {
|
||||
$sesKontrast = 0;
|
||||
}
|
||||
|
||||
$sessiondata['kontrast'] = $sesKontrast;
|
||||
|
||||
$GLOBALS['TSFE']->fe_user->setKey('ses', 'accessibility', $sessiondata);
|
||||
$GLOBALS['TSFE']->fe_user->storeSessionData();
|
||||
}
|
||||
|
||||
|
||||
if ($args['btn'] == 'schriftgroesse') {
|
||||
if (!array_key_exists('schriftgroesse', $sessiondata) || $sessiondata['schriftgroesse'] == 0) {
|
||||
$sesSchriftgroesse = 1;
|
||||
} else {
|
||||
$sesSchriftgroesse = 0;
|
||||
}
|
||||
|
||||
$sessiondata['schriftgroesse'] = $sesSchriftgroesse;
|
||||
|
||||
$GLOBALS['TSFE']->fe_user->setKey('ses', 'accessibility', $sessiondata);
|
||||
$GLOBALS['TSFE']->fe_user->storeSessionData();
|
||||
}
|
||||
}
|
||||
|
||||
return json_encode($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Ifabrik\IfAccessButtons\Domain\Model;
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2016 Marco Kuprat <mk@internetfabrik.de>, Internetfabrik GmbH
|
||||
*
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
/**
|
||||
* AccessibilityButtons
|
||||
*/
|
||||
class AccessibilityButtons extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Ifabrik\IfAccessButtons\Domain\Repository;
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2016 Marco Kuprat <mk@internetfabrik.de>, Internetfabrik GmbH
|
||||
*
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
/**
|
||||
* The repository for AccessibilityButtons
|
||||
*/
|
||||
class AccessibilityButtonsRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#
|
||||
# Extension Builder settings for extension if_access_buttons
|
||||
# generated 2016-02-08T08:21:00Z
|
||||
#
|
||||
# See http://www.yaml.org/spec/1.2/spec.html
|
||||
#
|
||||
|
||||
---
|
||||
|
||||
########### Overwrite settings ###########
|
||||
#
|
||||
# These settings only apply, if the roundtrip feature of the extension builder
|
||||
# is enabled in the extension manager
|
||||
#
|
||||
# Usage:
|
||||
# nesting reflects the file structure
|
||||
# a setting applies to a file or recursive to all files and subfolders
|
||||
#
|
||||
# merge:
|
||||
# means for classes: All properties ,methods and method bodies
|
||||
# of the existing class will be modified according to the new settings
|
||||
# but not overwritten
|
||||
#
|
||||
# for locallang xlf files: Existing keys and labels are always
|
||||
# preserved (renaming a property or DomainObject will result in new keys and new labels)
|
||||
#
|
||||
# for other files: You will find a Split token at the end of the file
|
||||
# see: \EBT\ExtensionBuilder\Service\RoundTrip::SPLIT_TOKEN
|
||||
#
|
||||
# After this token you can write whatever you want and it will be appended
|
||||
# everytime the code is generated
|
||||
#
|
||||
# keep:
|
||||
# files are never overwritten
|
||||
# These settings may break the functionality of the extension builder!
|
||||
# Handle with care!
|
||||
#
|
||||
#
|
||||
|
||||
############ extension settings ##############
|
||||
|
||||
overwriteSettings:
|
||||
Classes:
|
||||
Controller: merge
|
||||
Domain:
|
||||
Model: merge
|
||||
Repository: merge
|
||||
|
||||
Configuration:
|
||||
#TCA: merge
|
||||
#TypoScript: keep
|
||||
|
||||
Resources:
|
||||
Private:
|
||||
#Language: merge
|
||||
#Templates: keep
|
||||
|
||||
ext_icon.gif: keep
|
||||
|
||||
# ext_localconf.php: merge
|
||||
|
||||
# ext_tables.php: merge
|
||||
|
||||
# ext_tables.sql: merge
|
||||
|
||||
## use static date attribute in xliff files ##
|
||||
#staticDateInXliffFiles: 2016-02-08T08:21:00Z
|
||||
|
||||
## list of error codes for warnings that should be ignored ##
|
||||
#ignoreWarnings:
|
||||
#503
|
||||
|
||||
######### settings for classBuilder #############################
|
||||
#
|
||||
# here you may define default parent classes for your classes
|
||||
# these settings only apply for new generated classes
|
||||
# you may also just change the parent class in the generated class file.
|
||||
# It will be kept on next code generation, if the overwrite settings
|
||||
# are configured to merge it
|
||||
#
|
||||
#################################################################
|
||||
|
||||
classBuilder:
|
||||
|
||||
Controller:
|
||||
parentClass: \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
|
||||
|
||||
Model:
|
||||
AbstractEntity:
|
||||
parentClass: \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||
|
||||
AbstractValueObject:
|
||||
parentClass: \TYPO3\CMS\Extbase\DomainObject\AbstractValueObject
|
||||
|
||||
Repository:
|
||||
parentClass: \TYPO3\CMS\Extbase\Persistence\Repository
|
||||
|
||||
setDefaultValuesForClassProperties: true
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
return array(
|
||||
'ctrl' => array(
|
||||
'title' => 'LLL:EXT:if_access_buttons/Resources/Private/Language/locallang_db.xlf:tx_ifaccessbuttons_domain_model_accessibilitybuttons',
|
||||
'label' => 'uid',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'cruser_id' => 'cruser_id',
|
||||
'dividers2tabs' => TRUE,
|
||||
'versioningWS' => 2,
|
||||
'versioning_followPages' => TRUE,
|
||||
|
||||
'languageField' => 'sys_language_uid',
|
||||
'transOrigPointerField' => 'l10n_parent',
|
||||
'transOrigDiffSourceField' => 'l10n_diffsource',
|
||||
|
||||
'enablecolumns' => array(
|
||||
|
||||
),
|
||||
'searchFields' => '',
|
||||
'iconfile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('if_access_buttons') . 'Resources/Public/Icons/tx_ifaccessbuttons_domain_model_accessibilitybuttons.gif'
|
||||
),
|
||||
'interface' => array(
|
||||
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, ',
|
||||
),
|
||||
'types' => array(
|
||||
'1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, '),
|
||||
),
|
||||
'palettes' => array(
|
||||
'1' => array('showitem' => ''),
|
||||
),
|
||||
'columns' => array(
|
||||
|
||||
'sys_language_uid' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.language',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'foreign_table' => 'sys_language',
|
||||
'foreign_table_where' => 'ORDER BY sys_language.title',
|
||||
'items' => array(
|
||||
array('LLL:EXT:lang/locallang_general.xlf:LGL.allLanguages', -1),
|
||||
array('LLL:EXT:lang/locallang_general.xlf:LGL.default_value', 0)
|
||||
),
|
||||
),
|
||||
),
|
||||
'l10n_parent' => array(
|
||||
'displayCond' => 'FIELD:sys_language_uid:>:0',
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'items' => array(
|
||||
array('', 0),
|
||||
),
|
||||
'foreign_table' => 'tx_ifaccessbuttons_domain_model_accessibilitybuttons',
|
||||
'foreign_table_where' => 'AND tx_ifaccessbuttons_domain_model_accessibilitybuttons.pid=###CURRENT_PID### AND tx_ifaccessbuttons_domain_model_accessibilitybuttons.sys_language_uid IN (-1,0)',
|
||||
),
|
||||
),
|
||||
'l10n_diffsource' => array(
|
||||
'config' => array(
|
||||
'type' => 'passthrough',
|
||||
),
|
||||
),
|
||||
|
||||
't3ver_label' => array(
|
||||
'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.versionLabel',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
'max' => 255,
|
||||
)
|
||||
),
|
||||
|
||||
),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
plugin.tx_ifaccessbuttons_pi1 {
|
||||
view {
|
||||
# cat=plugin.tx_ifaccessbuttons_pi1/file; type=string; label=Path to template root (FE)
|
||||
templateRootPath = EXT:if_access_buttons/Resources/Private/Templates/
|
||||
# cat=plugin.tx_ifaccessbuttons_pi1/file; type=string; label=Path to template partials (FE)
|
||||
partialRootPath = EXT:if_access_buttons/Resources/Private/Partials/
|
||||
# cat=plugin.tx_ifaccessbuttons_pi1/file; type=string; label=Path to template layouts (FE)
|
||||
layoutRootPath = EXT:if_access_buttons/Resources/Private/Layouts/
|
||||
}
|
||||
persistence {
|
||||
# cat=plugin.tx_ifaccessbuttons_pi1//a; type=string; label=Default storage PID
|
||||
storagePid =
|
||||
}
|
||||
|
||||
settings {
|
||||
# cat=plugin.tx_ifaccessbuttons_pi1/file; type=string; label=LLL:EXT:if_access_buttons/Resources/Private/Language/locallang.xlf:const.settings.cssFileKontrast
|
||||
cssFileKontrast = EXT:if_access_buttons/Resources/Public/Css/kontrast.css
|
||||
|
||||
# cat=plugin.tx_ifaccessbuttons_pi1/file; type=string; label=LLL:EXT:if_access_buttons/Resources/Private/Language/locallang.xlf:const.settings.cssFileFontsize
|
||||
cssFileFontsize = EXT:if_access_buttons/Resources/Public/Css/schrift-gross.css
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
plugin.tx_ifaccessbuttons_pi1 {
|
||||
view {
|
||||
templateRootPath = {$plugin.tx_ifaccessbuttons_pi1.view.templateRootPath}
|
||||
partialRootPath = {$plugin.tx_ifaccessbuttons_pi1.view.partialRootPath}
|
||||
layoutRootPath = {$plugin.tx_ifaccessbuttons_pi1.view.layoutRootPath}
|
||||
}
|
||||
persistence {
|
||||
storagePid = {$plugin.tx_ifaccessbuttons_pi1.persistence.storagePid}
|
||||
}
|
||||
|
||||
settings {
|
||||
cssFileKontrast = {$plugin.tx_ifaccessbuttons_pi1.settings.cssFileKontrast}
|
||||
|
||||
cssFileFontsize = {$plugin.tx_ifaccessbuttons_pi1.settings.cssFileFontsize}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _admin-manual:
|
||||
|
||||
Administrator Manual
|
||||
====================
|
||||
|
||||
Target group: **Administrators**
|
||||
|
||||
Describes how to manage the extension from an administrator point of view.
|
||||
That relates to Page/User TSconfig, permissions, configuration etc.,
|
||||
which administrator level users have access to.
|
||||
|
||||
Language should be non / semi-technical, explaining, using small examples.
|
||||
|
||||
|
||||
.. _admin-installation:
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
- How should the extension be installed?
|
||||
- Are they dependencies to resolve?
|
||||
- Is it a static template file to be included?
|
||||
|
||||
To install the extension, perform the following steps:
|
||||
|
||||
#. Go to the Extension Manager
|
||||
#. Install the extension
|
||||
#. Load the static template
|
||||
#. ...
|
||||
|
||||
For a list of configuration options, using a definition list is recommended:
|
||||
|
||||
Some Configuration
|
||||
This option enables...
|
||||
|
||||
Other configuration
|
||||
This other option is for all the rest...
|
||||
|
||||
|
||||
.. figure:: ../Images/AdministratorManual/ExtensionManager.png
|
||||
:alt: Extension Manager
|
||||
|
||||
Extension Manager (caption of the image)
|
||||
|
||||
List of extensions within the Extension Manager also shorten with "EM" (legend of the image)
|
||||
|
||||
|
||||
.. _admin-configuration:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
* Where and how the extension should be configured? TypoScript? PHP?
|
||||
|
||||
* Are there other prerequisite to full fill beforehand?
|
||||
For example, configure a setting in a special way somewhere.
|
||||
|
||||
|
||||
.. _admin-faq:
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
Possible subsection: FAQ
|
||||
|
||||
Subsection
|
||||
^^^^^^^^^^
|
||||
|
||||
Some subsection
|
||||
|
||||
Sub-subsection
|
||||
""""""""""""""
|
||||
|
||||
Deeper into the structure...
|
||||
@@ -0,0 +1,16 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _changelog:
|
||||
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
Providing a change log chapter is optional. You can also refer
|
||||
users to the ChangeLog file inside the extension or to some repository's
|
||||
commit listing.
|
||||
@@ -0,0 +1,106 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _configuration:
|
||||
|
||||
Configuration Reference
|
||||
=======================
|
||||
|
||||
Technical information: Installation, Reference of TypoScript options,
|
||||
configuration options on system level, how to extend it, the technical
|
||||
details, how to debug it and so on.
|
||||
|
||||
Language should be technical, assuming developer knowledge of TYPO3.
|
||||
Small examples/visuals are always encouraged.
|
||||
|
||||
Target group: **Developers**
|
||||
|
||||
|
||||
.. _configuration-typoscript:
|
||||
|
||||
TypoScript Reference
|
||||
--------------------
|
||||
|
||||
Possible subsections: Reference of TypoScript options.
|
||||
The construct below show the recommended structure for
|
||||
TypoScript properties listing and description.
|
||||
|
||||
Properties should be listed in the order in which they
|
||||
are executed by your extension, but the first should be
|
||||
alphabetical for easier access.
|
||||
|
||||
When detailing data types or standard TypoScript
|
||||
features, don't hesitate to cross-link to the TypoScript
|
||||
Reference as shown below. See the :file:`Settings.yml`
|
||||
file for the declaration of cross-linking keys.
|
||||
|
||||
|
||||
Properties
|
||||
^^^^^^^^^^
|
||||
|
||||
.. container:: ts-properties
|
||||
|
||||
=========================== ===================================== ======================= ====================
|
||||
Property Data type :ref:`t3tsref:stdwrap` Default
|
||||
=========================== ===================================== ======================= ====================
|
||||
allWrap_ :ref:`t3tsref:data-type-wrap` yes :code:`<div>|</div>`
|
||||
`subst\_elementUid`_ :ref:`t3tsref:data-type-boolean` no 0
|
||||
wrapItemAndSub_ :ref:`t3tsref:data-type-wrap`
|
||||
=========================== ===================================== ======================= ====================
|
||||
|
||||
|
||||
Property details
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
.. _ts-plugin-tx-extensionkey-stdwrap:
|
||||
|
||||
allWrap
|
||||
"""""""
|
||||
|
||||
:typoscript:`plugin.tx_extensionkey.allWrap =` :ref:`t3tsref:data-type-wrap`
|
||||
|
||||
Wraps the whole item.
|
||||
|
||||
|
||||
.. _ts-plugin-tx-extensionkey-wrapitemandsub:
|
||||
|
||||
wrapItemAndSub
|
||||
""""""""""""""
|
||||
|
||||
:typoscript:`plugin.tx_extensionkey.wrapItemAndSub =` :ref:`t3tsref:data-type-wrap`
|
||||
|
||||
Wraps the whole item and any submenu concatenated to it.
|
||||
|
||||
|
||||
.. _ts-plugin-tx-extensionkey-substelementUid:
|
||||
|
||||
subst_elementUid
|
||||
""""""""""""""""
|
||||
|
||||
:typoscript:`plugin.tx_extensionkey.subst_elementUid =` :ref:`t3tsref:data-type-boolean`
|
||||
|
||||
If set, all appearances of the string ``{elementUid}`` in the total
|
||||
element html-code (after wrapped in allWrap_) are substituted with the
|
||||
uid number of the menu item. This is useful if you want to insert an
|
||||
identification code in the HTML in order to manipulate properties with
|
||||
JavaScript.
|
||||
|
||||
|
||||
.. _configuration-faq:
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
Possible subsection: FAQ
|
||||
@@ -0,0 +1,60 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _developer:
|
||||
|
||||
Developer Corner
|
||||
================
|
||||
|
||||
Target group: **Developers**
|
||||
|
||||
Use this section for *providing code examples* or any **useful** information code wise.
|
||||
|
||||
|
||||
.. _developer-hooks:
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
Possible hook examples. Input parameters are:
|
||||
|
||||
+----------------+---------------+---------------------------------+
|
||||
| Parameter | Data type | Description |
|
||||
+================+===============+=================================+
|
||||
| $table | string | Name of the table |
|
||||
+----------------+---------------+---------------------------------+
|
||||
| $field | string | Name of the field |
|
||||
+----------------+---------------+---------------------------------+
|
||||
|
||||
Use parameter :code:`$table` to retrieve the table name...
|
||||
|
||||
.. _developer-api:
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
How to use the API...
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
$stuff = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||
'\\Foo\\Bar\\Utility\\Stuff'
|
||||
);
|
||||
$stuff->do();
|
||||
|
||||
or some other language:
|
||||
|
||||
.. code-block:: javascript
|
||||
:linenos:
|
||||
:emphasize-lines: 2-4
|
||||
|
||||
$(document).ready(
|
||||
function () {
|
||||
doStuff();
|
||||
}
|
||||
);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 153 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 226 KiB |
@@ -0,0 +1,21 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. This is 'Includes.txt'. It is included at the very top of each and
|
||||
every ReST source file in this documentation project (= manual).
|
||||
|
||||
|
||||
.. ==================================================
|
||||
.. DEFINE SOME TEXT ROLES
|
||||
.. --------------------------------------------------
|
||||
|
||||
.. role:: typoscript(code)
|
||||
|
||||
.. role:: ts(typoscript)
|
||||
:class: typoscript
|
||||
|
||||
.. role:: php(code)
|
||||
|
||||
.. highlight:: php
|
||||
64
typo3conf/ext/if_access_buttons/Documentation.tmpl/Index.rst
Normal file
64
typo3conf/ext/if_access_buttons/Documentation.tmpl/Index.rst
Normal file
@@ -0,0 +1,64 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: Includes.txt
|
||||
|
||||
.. _start:
|
||||
|
||||
=============================================================
|
||||
Accessibility Buttons
|
||||
=============================================================
|
||||
|
||||
.. only:: html
|
||||
|
||||
:Classification:
|
||||
if_access_buttons
|
||||
|
||||
:Version:
|
||||
|release|
|
||||
|
||||
:Language:
|
||||
en
|
||||
|
||||
:Description:
|
||||
Accessibility Buttons (Contrast, Fontsize)
|
||||
|
||||
:Keywords:
|
||||
comma,separated,list,of,keywords
|
||||
|
||||
:Copyright:
|
||||
2016
|
||||
|
||||
:Author:
|
||||
Marco Kuprat
|
||||
|
||||
:Email:
|
||||
mk@internetfabrik.de
|
||||
|
||||
:License:
|
||||
This document is published under the Open Content License
|
||||
available from http://www.opencontent.org/opl.shtml
|
||||
|
||||
:Rendered:
|
||||
|today|
|
||||
|
||||
The content of this document is related to TYPO3,
|
||||
a GNU/GPL CMS/Framework available from `www.typo3.org <http://www.typo3.org/>`_.
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:titlesonly:
|
||||
|
||||
Introduction/Index
|
||||
User/Index
|
||||
Administrator/Index
|
||||
Configuration/Index
|
||||
Developer/Index
|
||||
KnownProblems/Index
|
||||
ToDoList/Index
|
||||
ChangeLog/Index
|
||||
Links
|
||||
@@ -0,0 +1,46 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _introduction:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
|
||||
.. _what-it-does:
|
||||
|
||||
What does it do?
|
||||
----------------
|
||||
|
||||
This chapter should give a brief overview of the extension. What does it do? What problems does it solve?
|
||||
Who is interested in this? Basically, this section includes everything people need to know to decide whether they
|
||||
should go on with this extension or not.
|
||||
|
||||
.. important::
|
||||
|
||||
Please don't forget to repeat your extension's version number in the
|
||||
:file:`Settings.yml` file, in the :code:`release` property. It will be
|
||||
automatically picked up on the cover page by the :code:`|release|`
|
||||
substitution.
|
||||
|
||||
|
||||
.. _screenshots:
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
|
||||
This chapter should help people figure how the extension works. Remove it
|
||||
if not relevant.
|
||||
|
||||
.. figure:: ../Images/IntroductionPackage.png
|
||||
:width: 500px
|
||||
:alt: Introduction Package
|
||||
|
||||
Introduction Package just after installation (caption of the image)
|
||||
|
||||
How the Frontend of the Introduction Package looks like just after installation (legend of the image)
|
||||
@@ -0,0 +1,17 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _known-problems:
|
||||
|
||||
Known Problems
|
||||
==============
|
||||
|
||||
Say where bugs can be reported / followed up. Is it a
|
||||
`bug tracker <http://forge.typo3.org/projects/typo3cms-doc-official-extension-template/issues>`_?
|
||||
Use this section for informing about any type of of problem
|
||||
that are not necessarily named in the bug tracker such as performance issues, ...
|
||||
24
typo3conf/ext/if_access_buttons/Documentation.tmpl/Links.rst
Normal file
24
typo3conf/ext/if_access_buttons/Documentation.tmpl/Links.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: Includes.txt
|
||||
|
||||
|
||||
.. _links:
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
:TER:
|
||||
https://typo3.org/extensions/repository/view/<extension key>
|
||||
|
||||
:Bug Tracker:
|
||||
https://forge.typo3.org/projects/extension-<extension key>/issues
|
||||
|
||||
:Git Repository:
|
||||
https://github.com/<username>/<extension key>
|
||||
|
||||
:Contact:
|
||||
`@<username> <https://twitter.com/your-username>`__
|
||||
@@ -0,0 +1,65 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _start:
|
||||
|
||||
=============================================================
|
||||
###PROJECT_NAME### (Deutsch)
|
||||
=============================================================
|
||||
|
||||
.. only:: html
|
||||
|
||||
:Klassifikation:
|
||||
extension_key
|
||||
|
||||
:Version:
|
||||
|release|
|
||||
|
||||
:Sprache:
|
||||
de
|
||||
|
||||
:Beschreibung:
|
||||
Geben Sie eine Beschreibung ein.
|
||||
|
||||
:Schlüsselwörter:
|
||||
komma-getrennte,Liste,von,Schlüsselwörtern
|
||||
|
||||
:Copyright:
|
||||
###YEAR###
|
||||
|
||||
:Autor:
|
||||
###AUTHOR###
|
||||
|
||||
:E-Mail:
|
||||
author@example.com
|
||||
|
||||
:Lizenz:
|
||||
Dieses Dokument wird unter der Open Publication License, siehe
|
||||
http://www.opencontent.org/openpub/ veröffentlicht.
|
||||
|
||||
:Gerendert:
|
||||
|today|
|
||||
|
||||
Der Inhalt dieses Dokuments bezieht sich auf TYPO3,
|
||||
ein GNU/GPL CMS-Framework auf `www.typo3.org <https://typo3.org/>`__.
|
||||
|
||||
|
||||
**Inhaltsverzeichnis**
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:titlesonly:
|
||||
|
||||
.. Introduction/Index
|
||||
.. UserManual/Index
|
||||
.. AdministratorManual/Index
|
||||
.. Configuration/Index
|
||||
.. DeveloperCorner/Index
|
||||
.. KnownProblems/Index
|
||||
.. ToDoList/Index
|
||||
.. ChangeLog/Index
|
||||
@@ -0,0 +1,24 @@
|
||||
How to translate
|
||||
================
|
||||
|
||||
This directory contains the German translation of your documentation.
|
||||
This is a complete Sphinx project but you may reuse assets from the
|
||||
main documentation under Documentation/.
|
||||
|
||||
If you plan to translate your documentation to German, you should
|
||||
rename this directory and remove the suffix ".tmpl":
|
||||
|
||||
Localization.de_DE.tmpl -> Localization.de_DE
|
||||
|
||||
As this file is not needed either, feel free to delete it as well.
|
||||
|
||||
|
||||
Supported languages
|
||||
===================
|
||||
|
||||
Please visit http://sphinx-doc.org/latest/config.html#intl-options for a
|
||||
list of languages supported by Sphinx.
|
||||
|
||||
Please note however that TYPO3 is using locales so you may need to
|
||||
extend the language code from Sphinx into a proper locale to be used
|
||||
by TYPO3.
|
||||
@@ -0,0 +1,29 @@
|
||||
# This is the project specific Settings.yml file.
|
||||
# Place Sphinx specific build information here.
|
||||
# Settings given here will replace the settings of 'conf.py'.
|
||||
|
||||
# Below is an example of intersphinx mapping declaration
|
||||
# Add more mappings depending on what manual you want to link to
|
||||
# Remove entirely if you don't need cross-linking
|
||||
|
||||
---
|
||||
conf.py:
|
||||
copyright: 2012-2015
|
||||
project: Extension Name (Deutsch)
|
||||
version: x.y
|
||||
release: x.y.z
|
||||
intersphinx_mapping:
|
||||
t3tsref:
|
||||
- https://docs.typo3.org/typo3cms/TyposcriptReference/
|
||||
- null
|
||||
latex_documents:
|
||||
- - Index
|
||||
- <extension_key>.tex
|
||||
- Extension Name (Français)
|
||||
- Your Name
|
||||
- manual
|
||||
latex_elements:
|
||||
papersize: a4paper
|
||||
pointsize: 10pt
|
||||
preamble: \usepackage{typo3}
|
||||
...
|
||||
@@ -0,0 +1,65 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _start:
|
||||
|
||||
=============================================================
|
||||
###PROJECT_NAME### (Français)
|
||||
=============================================================
|
||||
|
||||
.. only:: html
|
||||
|
||||
:Classification:
|
||||
extension_key
|
||||
|
||||
:Version:
|
||||
|release|
|
||||
|
||||
:Langue:
|
||||
fr
|
||||
|
||||
:Description:
|
||||
entrez une description.
|
||||
|
||||
:Mots-clés:
|
||||
list,mots-clés,séparés,par,virgules
|
||||
|
||||
:Copyright:
|
||||
###YEAR###
|
||||
|
||||
:Auteur:
|
||||
###AUTHOR###
|
||||
|
||||
:E-mail:
|
||||
author@example.com
|
||||
|
||||
:Licence:
|
||||
Ce document est publié sous la licence de publication libre
|
||||
disponible sur http://www.opencontent.org/openpub/
|
||||
|
||||
:Généré:
|
||||
|today|
|
||||
|
||||
Le contenu de ce document est en relation avec TYPO3,
|
||||
un CMS/Framework GNU/GPL disponible sur `www.typo3.org <https://typo3.org/>`__.
|
||||
|
||||
|
||||
**Sommaire**
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:titlesonly:
|
||||
|
||||
.. Introduction/Index
|
||||
.. UserManual/Index
|
||||
.. AdministratorManual/Index
|
||||
.. Configuration/Index
|
||||
.. DeveloperCorner/Index
|
||||
.. KnownProblems/Index
|
||||
.. ToDoList/Index
|
||||
.. ChangeLog/Index
|
||||
@@ -0,0 +1,24 @@
|
||||
How to translate
|
||||
================
|
||||
|
||||
This directory contains the French translation of your documentation.
|
||||
This is a complete Sphinx project but you may reuse assets from the
|
||||
main documentation under Documentation/.
|
||||
|
||||
If you plan to translate your documentation to French, you should
|
||||
rename this directory and remove the suffix ".tmpl":
|
||||
|
||||
Localization.fr_FR.tmpl -> Localization.fr_FR
|
||||
|
||||
As this file is not needed either, feel free to delete it as well.
|
||||
|
||||
|
||||
Supported languages
|
||||
===================
|
||||
|
||||
Please visit http://sphinx-doc.org/latest/config.html#intl-options for a
|
||||
list of languages supported by Sphinx.
|
||||
|
||||
Please note however that TYPO3 is using locales so you may need to
|
||||
extend the language code from Sphinx into a proper locale to be used
|
||||
by TYPO3.
|
||||
@@ -0,0 +1,29 @@
|
||||
# This is the project specific Settings.yml file.
|
||||
# Place Sphinx specific build information here.
|
||||
# Settings given here will replace the settings of 'conf.py'.
|
||||
|
||||
# Below is an example of intersphinx mapping declaration
|
||||
# Add more mappings depending on what manual you want to link to
|
||||
# Remove entirely if you don't need cross-linking
|
||||
|
||||
---
|
||||
conf.py:
|
||||
copyright: 2012-2015
|
||||
project: Extension Name (Français)
|
||||
version: x.y
|
||||
release: x.y.z
|
||||
intersphinx_mapping:
|
||||
t3tsref:
|
||||
- https://docs.typo3.org/typo3cms/TyposcriptReference/
|
||||
- null
|
||||
latex_documents:
|
||||
- - Index
|
||||
- <extension_key>.tex
|
||||
- Extension Name (Français)
|
||||
- Your Name
|
||||
- manual
|
||||
latex_elements:
|
||||
papersize: a4paper
|
||||
pointsize: 10pt
|
||||
preamble: \usepackage{typo3}
|
||||
...
|
||||
@@ -0,0 +1,32 @@
|
||||
# This is the project specific Settings.yml file.
|
||||
# Place Sphinx specific build information here.
|
||||
# Settings given here will replace the settings of 'conf.py'.
|
||||
|
||||
# Below is an example of intersphinx mapping declaration
|
||||
# Add more mappings depending on what manual you want to link to
|
||||
# Remove entirely if you don't need cross-linking
|
||||
|
||||
---
|
||||
conf.py:
|
||||
copyright: 2016
|
||||
project: Accessibility Buttons
|
||||
version:
|
||||
release:
|
||||
intersphinx_mapping:
|
||||
t3tsref:
|
||||
- http://docs.typo3.org/typo3cms/TyposcriptReference/
|
||||
- null
|
||||
latex_documents:
|
||||
- - Index
|
||||
- if_access_buttons.tex
|
||||
- Accessibility Buttons
|
||||
- Marco Kuprat
|
||||
- manual
|
||||
latex_elements:
|
||||
papersize: a4paper
|
||||
pointsize: 10pt
|
||||
preamble: \usepackage
|
||||
html_theme_options:
|
||||
github_repository: TYPO3-Documentation/TYPO3CMS-Example-ExtensionManual
|
||||
github_branch: latest
|
||||
...
|
||||
@@ -0,0 +1,16 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _todo:
|
||||
|
||||
To-Do list
|
||||
==========
|
||||
|
||||
Give a link pointing to a `roadmap <http://forge.typo3.org/projects/typo3cms-doc-official-extension-template/roadmap>`_.
|
||||
Alternatively, you can dress up a list of things you want to add or fix in this chapter
|
||||
or give a vision about where the extension is heading.
|
||||
@@ -0,0 +1,67 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _user-manual:
|
||||
|
||||
Users Manual
|
||||
============
|
||||
|
||||
Target group: **Editors**
|
||||
|
||||
Here should be described how to use the extension from the editor perspective.
|
||||
|
||||
- How does it work?
|
||||
|
||||
- works well when doing this.
|
||||
|
||||
- does not work so well when doing that
|
||||
but we can live with it.
|
||||
|
||||
- **mind indentation when nesting lists**.
|
||||
|
||||
- How to install the plugin on a web page?
|
||||
|
||||
- What options are available?
|
||||
|
||||
Language should be non-technical, explaining, using small examples.
|
||||
Don't use to many acronyms unless they have been explained.
|
||||
Don't be confusing by putting information targeting administrators.
|
||||
|
||||
.. tip::
|
||||
|
||||
Take a break from time to time.
|
||||
|
||||
Admonitions should be used to warn the users about potential
|
||||
pitfalls, attract their attention to important elements
|
||||
or just add some notes for for information (further reading,
|
||||
for example).
|
||||
|
||||
.. important::
|
||||
|
||||
Remember to always say "please" when asking your software to
|
||||
do something.
|
||||
|
||||
Provide screenshots as needed for making things clear. When creating
|
||||
screenshots, try using the `Introduction Package <http://demo.typo3.org/>`_
|
||||
as a neutral TYPO3 CMS instance.
|
||||
|
||||
.. figure:: ../Images/UserManual/BackendView.png
|
||||
:width: 500px
|
||||
:alt: Backend view
|
||||
|
||||
Default Backend view (caption of the image)
|
||||
|
||||
The Backend view of TYPO3 after the user has clicked on module "Page". (legend of the image)
|
||||
|
||||
|
||||
.. _user-faq:
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
Possible subsection: FAQ
|
||||
87
typo3conf/ext/if_access_buttons/ExtensionBuilder.json
Normal file
87
typo3conf/ext/if_access_buttons/ExtensionBuilder.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"modules": [
|
||||
{
|
||||
"config": {
|
||||
"position": [
|
||||
455,
|
||||
149
|
||||
]
|
||||
},
|
||||
"name": "New Model Object",
|
||||
"value": {
|
||||
"actionGroup": {
|
||||
"_default0_list": false,
|
||||
"_default1_show": true,
|
||||
"_default2_new_create": false,
|
||||
"_default3_edit_update": false,
|
||||
"_default4_delete": false,
|
||||
"customActions": []
|
||||
},
|
||||
"name": "AccessibilityButtons",
|
||||
"objectsettings": {
|
||||
"addDeletedField": false,
|
||||
"addHiddenField": false,
|
||||
"addStarttimeEndtimeFields": false,
|
||||
"aggregateRoot": true,
|
||||
"categorizable": false,
|
||||
"description": "",
|
||||
"mapToTable": "",
|
||||
"parentClass": "",
|
||||
"sorting": false,
|
||||
"type": "Entity",
|
||||
"uid": "806181693390"
|
||||
},
|
||||
"propertyGroup": {
|
||||
"properties": []
|
||||
},
|
||||
"relationGroup": {
|
||||
"relations": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"backendModules": [],
|
||||
"description": "Accessibility Buttons (Contrast, Fontsize)",
|
||||
"emConf": {
|
||||
"category": "plugin",
|
||||
"custom_category": "",
|
||||
"dependsOn": "typo3 => 6.2.0-6.2.99\n",
|
||||
"disableLocalization": false,
|
||||
"disableVersioning": false,
|
||||
"skipGenerateDocumentationTemplate": false,
|
||||
"sourceLanguage": "en",
|
||||
"state": "alpha",
|
||||
"version": ""
|
||||
},
|
||||
"extensionKey": "if_access_buttons",
|
||||
"name": "Accessibility Buttons",
|
||||
"originalExtensionKey": "",
|
||||
"persons": [
|
||||
{
|
||||
"company": "Internetfabrik GmbH",
|
||||
"email": "mk@internetfabrik.de",
|
||||
"name": "Marco Kuprat",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"plugins": [
|
||||
{
|
||||
"actions": {
|
||||
"controllerActionCombinations": "",
|
||||
"noncacheableActions": "",
|
||||
"switchableActions": ""
|
||||
},
|
||||
"key": "pi1",
|
||||
"name": "Accessibility Buttons"
|
||||
}
|
||||
],
|
||||
"vendorName": "Ifabrik"
|
||||
},
|
||||
"wires": [],
|
||||
"log": {
|
||||
"last_modified": "2016-02-08 08:24",
|
||||
"extension_builder_version": "6.2",
|
||||
"be_user": "Marco Kuprat (1)"
|
||||
}
|
||||
}
|
||||
11
typo3conf/ext/if_access_buttons/Resources/Private/.htaccess
Normal file
11
typo3conf/ext/if_access_buttons/Resources/Private/.htaccess
Normal file
@@ -0,0 +1,11 @@
|
||||
# Apache < 2.3
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy All
|
||||
</IfModule>
|
||||
|
||||
# Apache >= 2.3
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user