17 use Doctrine\DBAL\DBALException;
18 use Doctrine\DBAL\Driver\Statement;
19 use Psr\Log\LoggerAwareInterface;
20 use Psr\Log\LoggerAwareTrait;
79 use TYPO3\HtmlSanitizer\Builder\BuilderInterface;
109 'stdWrapPreProcess' =>
'hook',
111 'cacheRead' =>
'hook',
113 'setContentToCurrent' =>
'boolean',
114 'setContentToCurrent.' =>
'array',
115 'addPageCacheTags' =>
'string',
116 'addPageCacheTags.' =>
'array',
117 'setCurrent' =>
'string',
118 'setCurrent.' =>
'array',
122 'field' =>
'fieldName',
124 'current' =>
'boolean',
125 'current.' =>
'array',
126 'cObject' =>
'cObject',
127 'cObject.' =>
'array',
128 'numRows.' =>
'array',
132 'filelist.' =>
'array',
133 'preUserFunc' =>
'functionName',
134 'stdWrapOverride' =>
'hook',
136 'override' =>
'string',
137 'override.' =>
'array',
138 'preIfEmptyListNum' =>
'listNum',
139 'preIfEmptyListNum.' =>
'array',
140 'ifNull' =>
'string',
141 'ifNull.' =>
'array',
142 'ifEmpty' =>
'string',
143 'ifEmpty.' =>
'array',
144 'ifBlank' =>
'string',
145 'ifBlank.' =>
'array',
146 'listNum' =>
'listNum',
147 'listNum.' =>
'array',
150 'strPad.' =>
'array',
151 'stdWrap' =>
'stdWrap',
152 'stdWrap.' =>
'array',
153 'stdWrapProcess' =>
'hook',
155 'required' =>
'boolean',
156 'required.' =>
'array',
158 'fieldRequired' =>
'fieldName',
159 'fieldRequired.' =>
'array',
160 'csConv' =>
'string',
161 'csConv.' =>
'array',
162 'parseFunc' =>
'objectpath',
163 'parseFunc.' =>
'array',
164 'HTMLparser' =>
'boolean',
165 'HTMLparser.' =>
'array',
167 'replacement.' =>
'array',
168 'prioriCalc' =>
'boolean',
169 'prioriCalc.' =>
'array',
172 'intval' =>
'boolean',
173 'intval.' =>
'array',
176 'round' =>
'boolean',
178 'numberFormat.' =>
'array',
179 'expandList' =>
'boolean',
180 'expandList.' =>
'array',
181 'date' =>
'dateconf',
183 'strtotime' =>
'strtotimeconf',
184 'strtotime.' =>
'array',
185 'strftime' =>
'strftimeconf',
186 'strftime.' =>
'array',
191 'bytes' =>
'boolean',
193 'substring' =>
'parameters',
194 'substring.' =>
'array',
195 'cropHTML' =>
'crop',
196 'cropHTML.' =>
'array',
197 'stripHtml' =>
'boolean',
198 'stripHtml.' =>
'array',
201 'rawUrlEncode' =>
'boolean',
202 'rawUrlEncode.' =>
'array',
203 'htmlSpecialChars' =>
'boolean',
204 'htmlSpecialChars.' =>
'array',
205 'encodeForJavaScriptValue' =>
'boolean',
206 'encodeForJavaScriptValue.' =>
'array',
207 'doubleBrTag' =>
'string',
208 'doubleBrTag.' =>
'array',
213 'encapsLines.' =>
'array',
214 'keywords' =>
'boolean',
215 'keywords.' =>
'array',
216 'innerWrap' =>
'wrap',
217 'innerWrap.' =>
'array',
218 'innerWrap2' =>
'wrap',
219 'innerWrap2.' =>
'array',
221 'addParams.' =>
'array',
223 'filelink.' =>
'array',
224 'preCObject' =>
'cObject',
225 'preCObject.' =>
'array',
226 'postCObject' =>
'cObject',
227 'postCObject.' =>
'array',
228 'wrapAlign' =>
'align',
229 'wrapAlign.' =>
'array',
230 'typolink.' =>
'array',
233 'noTrimWrap' =>
'wrap',
234 'noTrimWrap.' =>
'array',
237 'dataWrap' =>
'dataWrap',
238 'dataWrap.' =>
'array',
239 'prepend' =>
'cObject',
240 'prepend.' =>
'array',
241 'append' =>
'cObject',
242 'append.' =>
'array',
245 'orderedStdWrap' =>
'stdWrap',
246 'orderedStdWrap.' =>
'array',
247 'outerWrap' =>
'wrap',
248 'outerWrap.' =>
'array',
249 'insertData' =>
'boolean',
250 'insertData.' =>
'array',
251 'postUserFunc' =>
'functionName',
252 'postUserFuncInt' =>
'functionName',
253 'prefixComment' =>
'string',
254 'prefixComment.' =>
'array',
255 'editIcons' =>
'string',
256 'editIcons.' =>
'array',
257 'editPanel' =>
'boolean',
258 'editPanel.' =>
'array',
259 'htmlSanitize' =>
'boolean',
260 'htmlSanitize.' =>
'array',
261 'cacheStore' =>
'hook',
263 'stdWrapPostProcess' =>
'hook',
265 'debug' =>
'boolean',
267 'debugFunc' =>
'boolean',
268 'debugFunc.' =>
'array',
269 'debugData' =>
'boolean',
270 'debugData.' =>
'array'
473 $this->contentObjectClassMap =
$GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'ContentObjects'];
485 $vars = get_object_vars($this);
486 unset($vars[
'typoScriptFrontendController'], $vars[
'logger']);
488 $this->currentFile =
'FileReference:' . $this->currentFile->getUid();
489 } elseif ($this->currentFile instanceof
File) {
490 $this->currentFile =
'File:' . $this->currentFile->getIdentifier();
492 unset($vars[
'currentFile']);
494 return array_keys($vars);
505 $this->typoScriptFrontendController =
$GLOBALS[
'TSFE'];
507 if ($this->currentFile !==
null && is_string($this->currentFile)) {
508 list($objectType, $identifier) = explode(
':', $this->currentFile, 2);
510 if ($objectType ===
'File') {
512 } elseif ($objectType ===
'FileReference') {
515 }
catch (ResourceDoesNotExistException $e) {
516 $this->currentFile =
null;
519 $this->logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__);
548 $this->contentObjectClassMap[$contentObjectName] = $className;
563 $this->currentRecord =
$table !==
''
564 ?
$table .
':' . ($this->data[
'uid'] ??
'')
566 $this->parameters = [];
567 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'cObjTypeAndClass'] ?? [] as $classArr) {
568 $this->cObjHookObjectsRegistry[$classArr[0]] = $classArr[1];
570 $this->stdWrapHookObjects = [];
571 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'stdWrap'] ?? [] as $className) {
572 $hookObject = GeneralUtility::makeInstance($className);
574 throw new \UnexpectedValueException($className .
' must implement interface ' . ContentObjectStdWrapHookInterface::class, 1195043965);
576 $this->stdWrapHookObjects[] = $hookObject;
578 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'postInit'] ?? [] as $className) {
579 $postInitializationProcessor = GeneralUtility::makeInstance($className);
581 throw new \UnexpectedValueException($className .
' must implement interface ' . ContentObjectPostInitHookInterface::class, 1274563549);
583 $postInitializationProcessor->postProcessContentObjectInitialization($this);
605 if (!isset($this->getImgResourceHookObjects)) {
606 $this->getImgResourceHookObjects = [];
607 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'getImgResource'] ?? [] as $className) {
608 $hookObject = GeneralUtility::makeInstance($className);
609 if (!$hookObject instanceof ContentObjectGetImageResourceHookInterface) {
610 throw new \UnexpectedValueException(
'$hookObject must implement interface ' . ContentObjectGetImageResourceHookInterface::class, 1218636383);
612 $this->getImgResourceHookObjects[] = $hookObject;
628 $this->parentRecord = [
672 public function cObjGet($setup, $addKey =
'')
674 if (!is_array($setup)) {
679 foreach ($sKeyArray as $theKey) {
680 $theValue = $setup[$theKey];
681 if ((
int)$theKey && strpos($theKey,
'.') ===
false) {
682 $conf = $setup[$theKey .
'.'];
683 $content .= $this->
cObjGetSingle($theValue, $conf, $addKey . $theKey);
706 if ($timeTracker->LR) {
707 $timeTracker->push($TSkey, $name);
710 if (isset($name[0]) && $name[0] ===
'<') {
711 $key = trim(substr($name, 1));
712 $cF = GeneralUtility::makeInstance(TypoScriptParser::class);
714 $confOverride = is_array($conf) ? $conf : [];
716 $conf = array_replace_recursive(is_array($conf) ? $conf : [], $confOverride);
718 $timeTracker->incStackPointer();
720 $timeTracker->decStackPointer();
724 if (!empty($this->cObjHookObjectsRegistry[$name])) {
725 if (empty($this->cObjHookObjectsArr[$name])) {
726 $this->cObjHookObjectsArr[$name] = GeneralUtility::makeInstance($this->cObjHookObjectsRegistry[$name]);
728 $hookObj = $this->cObjHookObjectsArr[$name];
729 if (method_exists($hookObj,
'cObjGetSingleExt')) {
730 $content .= $hookObj->cObjGetSingleExt($name, $conf, $TSkey, $this);
736 if ($contentObject) {
737 $content .= $this->
render($contentObject, $conf);
741 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'cObjTypeAndClassDefault'] ?? [] as $className) {
742 $hookObject = GeneralUtility::makeInstance($className);
743 if (!$hookObject instanceof ContentObjectGetSingleHookInterface) {
744 throw new \UnexpectedValueException(
'$hookObject must implement interface ' . ContentObjectGetSingleHookInterface::class, 1195043731);
747 $content .= $hookObject->getSingleContentObject($name, (array)$conf, $TSkey, $this);
751 $warning = sprintf(
'Content Object "%s" does not exist', $name);
752 $timeTracker->setTSlogMessage($warning, 2);
757 if ($timeTracker->LR) {
758 $timeTracker->pull($content);
777 if (!isset($this->contentObjectClassMap[$name])) {
780 $fullyQualifiedClassName = $this->contentObjectClassMap[$name];
781 $contentObject = GeneralUtility::makeInstance($fullyQualifiedClassName, $this);
783 throw new ContentRenderingException(sprintf(
'Registered content object class name "%s" must be an instance of AbstractContentObject, but is not!', $fullyQualifiedClassName), 1422564295);
785 return $contentObject;
805 public function render(AbstractContentObject $contentObject, $configuration = [])
810 $cacheConfiguration = $configuration[
'cache.'] ??
null;
811 if ($cacheConfiguration !==
null) {
812 unset($configuration[
'cache.']);
814 if ($cache !==
false) {
821 $content .= $contentObject->render($configuration);
822 }
catch (ContentRenderingException $exception) {
826 }
catch (\Exception $exception) {
828 if ($exceptionHandler ===
null) {
831 $content = $exceptionHandler->handle($exception, $contentObject, $configuration);
839 $cacheFrontend = GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_hash');
842 $cacheFrontend->set($key, $content, $tags, $lifetime);
859 $exceptionHandler =
null;
861 if (!empty($exceptionHandlerClassName)) {
863 if (!$exceptionHandler instanceof ExceptionHandlerInterface) {
864 throw new ContentRenderingException(
'An exception handler was configured but the class does not exist or does not implement the ExceptionHandlerInterface', 1403653369);
868 return $exceptionHandler;
879 $exceptionHandlerClassName =
null;
881 if (!isset($tsfe->config[
'config'][
'contentObjectExceptionHandler'])) {
882 if (GeneralUtility::getApplicationContext()->isProduction()) {
883 $exceptionHandlerClassName =
'1';
886 $exceptionHandlerClassName = $tsfe->config[
'config'][
'contentObjectExceptionHandler'];
889 if (isset($configuration[
'exceptionHandler'])) {
890 $exceptionHandlerClassName = $configuration[
'exceptionHandler'];
893 if ($exceptionHandlerClassName ===
'1') {
894 $exceptionHandlerClassName = ProductionExceptionHandler::class;
897 return $exceptionHandlerClassName;
909 $exceptionHandlerConfiguration = [];
911 if (!empty($tsfe->config[
'config'][
'contentObjectExceptionHandler.'])) {
912 $exceptionHandlerConfiguration = $tsfe->config[
'config'][
'contentObjectExceptionHandler.'];
914 if (!empty($configuration[
'exceptionHandler.'])) {
915 $exceptionHandlerConfiguration = array_replace_recursive($exceptionHandlerConfiguration, $configuration[
'exceptionHandler.']);
918 return $exceptionHandlerConfiguration;
949 if ($this->userObjectType !== self::OBJECTTYPE_USER) {
952 $this->doConvertToUserIntObject =
true;
970 if ($recursive ===
false && is_string($flexData)) {
971 $flexData = GeneralUtility::xml2array($flexData,
'T3');
973 if (is_array($flexData) && isset($flexData[
'data'][
'sDEF'][
'lDEF'])) {
974 $flexData = $flexData[
'data'][
'sDEF'][
'lDEF'];
976 if (!is_array($flexData)) {
979 foreach ($flexData as $key => $value) {
980 if (!is_array($value)) {
983 if (isset($value[
'el'])) {
984 if (is_array($value[
'el']) && !empty($value[
'el'])) {
985 foreach ($value[
'el'] as $ekey => $element) {
986 if (isset($element[
'vDEF'])) {
987 $conf[$ekey] = $element[
'vDEF'];
989 if (is_array($element)) {
1000 if (isset($value[
'vDEF'])) {
1001 $conf[$key] = $value[
'vDEF'];
1016 $pidList = isset($pidConf) ? trim($this->
stdWrap($pidList, $pidConf)) : trim($pidList);
1017 if ($pidList ===
'') {
1022 if (trim($pidList)) {
1023 $listArr = GeneralUtility::intExplode(
',', str_replace(
'this', $tsfe->contentPid, $pidList));
1027 if (is_array($listArr) && !empty($listArr)) {
1028 foreach ($listArr as $uid) {
1029 $page = $tsfe->sys_page->getPage($uid);
1030 if (!$page[
'is_siteroot']) {
1031 $pidList[] = $page[
'pid'];
1035 return implode(
',', $pidList);
1049 public function cImage($file, $conf)
1053 $tsfe->lastImageInfo = $info;
1054 if (!is_array($info)) {
1058 $source = $tsfe->absRefPrefix . str_replace(
'%2F',
'/', rawurlencode($info[
'3']));
1063 $layoutKey = $this->
stdWrap($conf[
'layoutKey'], $conf[
'layoutKey.']);
1068 $tsfe->imagesOnPage[] = $source;
1071 if ($params !==
'' && $params[0] !==
' ') {
1072 $params =
' ' . $params;
1076 'width' => (int)$info[0],
1077 'height' => (
int)$info[1],
1078 'src' => htmlspecialchars($source),
1079 'params' => $params,
1080 'altParams' => $altParam,
1081 'border' => $this->
getBorderAttr(
' border="' . (
int)$conf[
'border'] .
'"'),
1082 'sourceCollection' => $sourceCollection,
1083 'selfClosingTagSlash' => !empty($tsfe->xhtmlDoctype) ?
' /' :
'',
1086 $markerTemplateEngine = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
1087 $theValue = $markerTemplateEngine->substituteMarkerArray($imageTagTemplate, $imageTagValues,
'###|###',
true,
true);
1089 $linkWrap = isset($conf[
'linkWrap.']) ? $this->
stdWrap($conf[
'linkWrap'], $conf[
'linkWrap.']) : $conf[
'linkWrap'];
1091 $theValue = $this->
linkWrap($theValue, $linkWrap);
1092 } elseif ($conf[
'imageLinkWrap']) {
1093 $originalFile = !empty($info[
'originalFile']) ? $info[
'originalFile'] : $info[
'origFile'];
1094 $theValue = $this->
imageLinkWrap($theValue, $originalFile, $conf[
'imageLinkWrap.']);
1096 $wrap = isset($conf[
'wrap.']) ? $this->
stdWrap($conf[
'wrap'], $conf[
'wrap.']) : $conf[
'wrap'];
1097 if ((
string)$wrap !==
'') {
1098 $theValue = $this->
wrap($theValue, $conf[
'wrap']);
1113 $docType = $tsfe->xhtmlDoctype;
1115 $docType !==
'xhtml_strict' && $docType !==
'xhtml_11'
1116 && $tsfe->config[
'config'][
'doctype'] !==
'html5'
1117 && !$tsfe->config[
'config'][
'disableImgBorderAttr']
1134 if ($layoutKey && isset($conf[
'layout.']) && isset($conf[
'layout.'][$layoutKey .
'.'])) {
1136 $conf[
'layout.'][$layoutKey .
'.'][
'element'] ??
'',
1137 $conf[
'layout.'][$layoutKey .
'.'][
'element.'] ?? []
1140 $imageTagLayout =
'<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>';
1142 return $imageTagLayout;
1156 $sourceCollection =
'';
1158 && isset($conf[
'sourceCollection.']) && $conf[
'sourceCollection.']
1160 isset($conf[
'layout.'][$layoutKey .
'.'][
'source']) && $conf[
'layout.'][$layoutKey .
'.'][
'source']
1161 || isset($conf[
'layout.'][$layoutKey .
'.'][
'source.']) && $conf[
'layout.'][$layoutKey .
'.'][
'source.']
1166 $activeSourceCollections = [];
1167 foreach ($conf[
'sourceCollection.'] as $sourceCollectionKey => $sourceCollectionConfiguration) {
1168 if (substr($sourceCollectionKey, -1) ===
'.') {
1169 if (empty($sourceCollectionConfiguration[
'if.']) || $this->
checkIf($sourceCollectionConfiguration[
'if.'])) {
1170 $activeSourceCollections[] = $sourceCollectionConfiguration;
1177 $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
1178 $srcLayoutOptionSplitted = $typoScriptService->explodeConfigurationForOptionSplit((array)$conf[
'layout.'][$layoutKey .
'.'], count($activeSourceCollections));
1181 foreach ($activeSourceCollections as $key => $sourceConfiguration) {
1183 $srcLayoutOptionSplitted[$key][
'source'] ??
'',
1184 $srcLayoutOptionSplitted[$key][
'source.'] ?? []
1187 $sourceRenderConfiguration = [
1189 'file.' => $conf[
'file.'] ?? null
1192 if (isset($sourceConfiguration[
'quality']) || isset($sourceConfiguration[
'quality.'])) {
1193 $imageQuality = $sourceConfiguration[
'quality'] ??
'';
1194 if (isset($sourceConfiguration[
'quality.'])) {
1195 $imageQuality = $this->
stdWrap($sourceConfiguration[
'quality'], $sourceConfiguration[
'quality.']);
1197 if ($imageQuality) {
1198 $sourceRenderConfiguration[
'file.'][
'params'] =
'-quality ' . (int)$imageQuality;
1202 if (isset($sourceConfiguration[
'pixelDensity'])) {
1203 $pixelDensity = (int)$this->
stdWrap(
1204 $sourceConfiguration[
'pixelDensity'] ??
'',
1205 $sourceConfiguration[
'pixelDensity.'] ?? []
1210 $dimensionKeys = [
'width',
'height',
'maxW',
'minW',
'maxH',
'minH',
'maxWidth',
'maxHeight',
'XY'];
1211 foreach ($dimensionKeys as $dimensionKey) {
1213 $sourceConfiguration[$dimensionKey] ??
'',
1214 $sourceConfiguration[$dimensionKey .
'.'] ?? []
1218 $conf[
'file.'][$dimensionKey] ??
'',
1219 $conf[
'file.'][$dimensionKey .
'.'] ?? []
1223 if (strstr($dimension,
'c') !==
false && ($dimensionKey ===
'width' || $dimensionKey ===
'height')) {
1224 $dimensionParts = explode(
'c', $dimension, 2);
1225 $dimension = ((int)$dimensionParts[0] * $pixelDensity) .
'c';
1226 if ($dimensionParts[1]) {
1227 $dimension .= $dimensionParts[1];
1229 } elseif ($dimensionKey ===
'XY') {
1230 $dimensionParts = GeneralUtility::intExplode(
',', $dimension,
false, 2);
1231 $dimension = $dimensionParts[0] * $pixelDensity;
1232 if ($dimensionParts[1]) {
1233 $dimension .=
',' . $dimensionParts[1] * $pixelDensity;
1236 $dimension = (int)$dimension * $pixelDensity;
1238 $sourceRenderConfiguration[
'file.'][$dimensionKey] = $dimension;
1240 unset($sourceRenderConfiguration[
'file.'][$dimensionKey .
'.']);
1243 $sourceInfo = $this->
getImgResource($sourceRenderConfiguration[
'file'], $sourceRenderConfiguration[
'file.']);
1245 $sourceConfiguration[
'width'] = $sourceInfo[0];
1246 $sourceConfiguration[
'height'] = $sourceInfo[1];
1248 if (parse_url($sourceInfo[3], PHP_URL_HOST) ===
null) {
1249 $urlPrefix = $tsfe->absRefPrefix;
1251 $sourceConfiguration[
'src'] = htmlspecialchars($urlPrefix . $sourceInfo[3]);
1252 $sourceConfiguration[
'selfClosingTagSlash'] = !empty($tsfe->xhtmlDoctype) ?
' /' :
'';
1254 $markerTemplateEngine = GeneralUtility::makeInstance(MarkerBasedTemplateService::class);
1255 $oneSourceCollection = $markerTemplateEngine->substituteMarkerArray($sourceLayout, $sourceConfiguration,
'###|###',
true,
true);
1257 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'getImageSourceCollection'] ?? [] as $className) {
1258 $hookObject = GeneralUtility::makeInstance($className);
1260 throw new \UnexpectedValueException(
1261 '$hookObject must implement interface ' . ContentObjectOneSourceCollectionHookInterface::class,
1265 $oneSourceCollection = $hookObject->getOneSourceCollection((array)$sourceRenderConfiguration, (array)$sourceConfiguration, $oneSourceCollection, $this);
1268 $sourceCollection .= $oneSourceCollection;
1272 return $sourceCollection;
1286 $string = (string)$string;
1287 $enable = isset($conf[
'enable.']) ? $this->
stdWrap($conf[
'enable'], $conf[
'enable.']) : $conf[
'enable'];
1291 $content = (string)$this->
typoLink($string, $conf[
'typolink.']);
1292 if (isset($conf[
'file.'])) {
1293 $imageFile = $this->
stdWrap($imageFile, $conf[
'file.']);
1296 if ($imageFile instanceof File) {
1298 } elseif ($imageFile instanceof FileReference) {
1299 $file = $imageFile->getOriginalFile();
1309 if ($content === $string && $file !==
null) {
1310 $parameterNames = [
'width',
'height',
'effects',
'bodyTag',
'title',
'wrap',
'crop'];
1312 $sample = isset($conf[
'sample.']) ? $this->
stdWrap($conf[
'sample'], $conf[
'sample.']) : $conf[
'sample'];
1316 foreach ($parameterNames as $parameterName) {
1317 if (isset($conf[$parameterName .
'.'])) {
1318 $conf[$parameterName] = $this->
stdWrap($conf[$parameterName], $conf[$parameterName .
'.']);
1320 if (isset($conf[$parameterName]) && $conf[$parameterName]) {
1324 $parametersEncoded = base64_encode(json_encode(
$parameters));
1325 $hmac = GeneralUtility::hmac(implode(
'|', [$file->getUid(), $parametersEncoded]));
1326 $params =
'&md5=' . $hmac;
1327 foreach (str_split($parametersEncoded, 64) as $index => $chunk) {
1328 $params .=
'¶meters' . rawurlencode(
'[') . $index . rawurlencode(
']') .
'=' . rawurlencode($chunk);
1331 $directImageLink = isset($conf[
'directImageLink.']) ? $this->
stdWrap($conf[
'directImageLink'], $conf[
'directImageLink.']) : $conf[
'directImageLink'];
1332 if ($directImageLink) {
1333 $imgResourceConf = [
1334 'file' => $imageFile,
1346 if ($xhtmlDocType !==
'xhtml_strict' && $xhtmlDocType !==
'xhtml_11') {
1347 $target = isset($conf[
'target.'])
1348 ? (string)$this->
stdWrap($conf[
'target'], $conf[
'target.'])
1349 : (string)$conf[
'target'];
1350 if ($target ===
'') {
1351 $target =
'thePicture';
1356 $conf[
'JSwindow'] = isset($conf[
'JSwindow.']) ? $this->
stdWrap($conf[
'JSwindow'], $conf[
'JSwindow.']) : $conf[
'JSwindow'];
1357 if ($conf[
'JSwindow']) {
1358 if ($conf[
'JSwindow.'][
'altUrl'] || $conf[
'JSwindow.'][
'altUrl.']) {
1359 $altUrl = isset($conf[
'JSwindow.'][
'altUrl.']) ? $this->
stdWrap($conf[
'JSwindow.'][
'altUrl'], $conf[
'JSwindow.'][
'altUrl.']) : $conf[
'JSwindow.'][
'altUrl'];
1361 $url = $altUrl . ($conf[
'JSwindow.'][
'altUrl_noDefaultParams'] ?
'' :
'?file=' . rawurlencode($imageFile) . $params);
1366 $JSwindowExpand = isset($conf[
'JSwindow.'][
'expand.']) ? $this->
stdWrap($conf[
'JSwindow.'][
'expand'], $conf[
'JSwindow.'][
'expand.']) : $conf[
'JSwindow.'][
'expand'];
1367 $offset = GeneralUtility::intExplode(
',', $JSwindowExpand .
',');
1368 $newWindow = isset($conf[
'JSwindow.'][
'newWindow.']) ? $this->
stdWrap($conf[
'JSwindow.'][
'newWindow'], $conf[
'JSwindow.'][
'newWindow.']) : $conf[
'JSwindow.'][
'newWindow'];
1369 $onClick =
'openPic('
1371 .
'\'' . ($newWindow ? md5($url) :
'thePicture') .
'\','
1372 . GeneralUtility::quoteJSvalue(
'width=' . ($processedFile->getProperty(
'width') + $offset[0])
1373 .
',height=' . ($processedFile->getProperty(
'height') + $offset[1]) .
',status=0,menubar=0')
1374 .
'); return false;';
1375 $a1 =
'<a href="' . htmlspecialchars($url) .
'"'
1376 .
' onclick="' . htmlspecialchars($onClick) .
'"'
1377 . ($target !==
'' ?
' target="' . htmlspecialchars($target) .
'"' :
'')
1382 $conf[
'linkParams.'][
'directImageLink'] = (bool)$conf[
'directImageLink'];
1383 $conf[
'linkParams.'][
'parameter'] = $url;
1384 $string = $this->
typoLink($string, $conf[
'linkParams.']);
1386 if (isset($conf[
'stdWrap.'])) {
1387 $string = $this->
stdWrap($string, $conf[
'stdWrap.']);
1389 $content = $a1 . $string . $a2;
1404 $tstamp = (int)$tstamp;
1406 if ($tstamp > (
int)$tsfe->register[
'SYS_LASTCHANGED']) {
1407 $tsfe->register[
'SYS_LASTCHANGED'] = $tstamp;
1420 public function linkWrap($content, $wrap)
1422 $wrapArr = explode(
'|', $wrap);
1423 if (preg_match(
'/\\{([0-9]*)\\}/', $wrapArr[0], $reg)) {
1426 $wrapArr[0] = str_replace($reg[0], $uid, $wrapArr[0]);
1429 return trim($wrapArr[0] ??
'') . $content . trim($wrapArr[1] ??
'');
1443 $altText = isset($conf[
'altText.']) ? trim($this->
stdWrap($conf[
'altText'], $conf[
'altText.'])) : trim($conf[
'altText']);
1444 $titleText = isset($conf[
'titleText.']) ? trim($this->
stdWrap($conf[
'titleText'], $conf[
'titleText.'])) : trim($conf[
'titleText']);
1448 $longDescUrl = trim($conf[
'longdescURL']);
1450 $longDescUrl = strip_tags($longDescUrl);
1453 $altParam =
' alt="' . htmlspecialchars($altText) .
'"';
1455 $emptyTitleHandling = isset($conf[
'emptyTitleHandling.']) ? $this->
stdWrap($conf[
'emptyTitleHandling'], $conf[
'emptyTitleHandling.']) : $conf[
'emptyTitleHandling'];
1457 if ($titleText || $emptyTitleHandling ===
'keepEmpty') {
1458 $altParam .=
' title="' . htmlspecialchars($titleText) .
'"';
1459 } elseif (!$titleText && $emptyTitleHandling ===
'useAlt') {
1460 $altParam .=
' title="' . htmlspecialchars($altText) .
'"';
1463 if ($longDesc && !empty($longDescUrl)) {
1464 $altParam .=
' longdesc="' . htmlspecialchars($longDescUrl) .
'"';
1481 if ($conf[
'ATagParams.'] ??
false) {
1482 $aTagParams =
' ' . $this->
stdWrap($conf[
'ATagParams'], $conf[
'ATagParams.']);
1483 } elseif ($conf[
'ATagParams'] ??
false) {
1484 $aTagParams =
' ' . $conf[
'ATagParams'];
1492 'aTagParams' => &$aTagParams
1494 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'getATagParamsPostProc'] ?? [] as $className) {
1495 $processor = GeneralUtility::makeInstance($className);
1496 $aTagParams = $processor->process($_params, $this);
1499 $aTagParams = trim($aTagParams);
1500 if (!empty($aTagParams)) {
1501 $aTagParams =
' ' . $aTagParams;
1518 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'extLinkATagParamsHandler'])) {
1519 $extLinkATagParamsHandler = GeneralUtility::makeInstance(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'extLinkATagParamsHandler']);
1520 if (method_exists($extLinkATagParamsHandler,
'main')) {
1521 $out .= trim($extLinkATagParamsHandler->main($URL, $TYPE, $this));
1524 return trim($out) ?
' ' . trim($out) :
'';
1540 $this->currentFile = $fileObject;
1569 public function stdWrap($content =
'', $conf = [])
1571 $content = (string)$content;
1574 if ($this->stdWrapHookObjects) {
1575 $conf[
'stdWrapPreProcess'] = 1;
1576 $conf[
'stdWrapOverride'] = 1;
1577 $conf[
'stdWrapProcess'] = 1;
1578 $conf[
'stdWrapPostProcess'] = 1;
1581 if (!is_array($conf) || !$conf) {
1586 if (isset($conf[
'cache.']) && is_array($conf[
'cache.'])) {
1587 $conf[
'cache.'][
'key'] = $this->
stdWrap($conf[
'cache.'][
'key'], $conf[
'cache.'][
'key.']);
1588 $conf[
'cache.'][
'tags'] = $this->
stdWrap($conf[
'cache.'][
'tags'], $conf[
'cache.'][
'tags.']);
1589 $conf[
'cache.'][
'lifetime'] = $this->
stdWrap($conf[
'cache.'][
'lifetime'], $conf[
'cache.'][
'lifetime.']);
1590 $conf[
'cacheRead'] = 1;
1591 $conf[
'cacheStore'] = 1;
1594 $sortedConf = array_keys(array_intersect_key($this->stdWrapOrder, $conf));
1596 $stdWrapDisabledFunctionTypes =
'cObject,functionName,stdWrap';
1601 $this->stdWrapRecursionLevel++;
1604 foreach ($sortedConf as $stdWrapName) {
1606 if ((!isset($isExecuted[$stdWrapName]) || !$isExecuted[$stdWrapName]) && !$this->stopRendering[$this->stdWrapRecursionLevel]) {
1607 $functionName = rtrim($stdWrapName,
'.');
1608 $functionProperties = $functionName .
'.';
1609 $functionType = $this->stdWrapOrder[$functionName] ??
null;
1613 if (!empty($conf[$functionProperties]) && !GeneralUtility::inList($stdWrapDisabledFunctionTypes, $functionType)) {
1614 if (array_intersect_key($this->stdWrapOrder, $conf[$functionProperties])) {
1617 if (($functionName ===
'ifBlank' && $content !==
'') ||
1618 ($functionName ===
'ifEmpty' && trim($content) !==
'')) {
1622 $conf[$functionName] = $this->
stdWrap($conf[$functionName] ??
'', $conf[$functionProperties] ?? []);
1626 if ((isset($conf[$functionName]) || $conf[$functionProperties])
1627 && ($functionType !==
'boolean' || $conf[$functionName])
1631 $functionName => $conf[$functionName] ??
null,
1632 $functionProperties => $conf[$functionProperties] ?? null
1635 if ($functionType ===
'hook') {
1636 $singleConf = $conf;
1639 $isExecuted[$functionName] =
true;
1640 $isExecuted[$functionProperties] =
true;
1642 $functionName =
'stdWrap_' . $functionName;
1643 $content = $this->{$functionName}($content, $singleConf);
1644 } elseif ($functionType ===
'boolean' && !$conf[$functionName]) {
1645 $isExecuted[$functionName] =
true;
1646 $isExecuted[$functionProperties] =
true;
1650 unset($this->stopRendering[$this->stdWrapRecursionLevel]);
1651 $this->stdWrapRecursionLevel--;
1664 public function stdWrapValue($key, array $config, $defaultValue =
'')
1666 if (isset($config[$key])) {
1667 if (!isset($config[$key .
'.'])) {
1668 return $config[$key];
1670 } elseif (isset($config[$key .
'.'])) {
1673 return $defaultValue;
1675 $stdWrapped = $this->
stdWrap($config[$key], $config[$key .
'.']);
1676 return $stdWrapped ?: $defaultValue;
1690 foreach ($this->stdWrapHookObjects as $hookObject) {
1692 $content = $hookObject->stdWrapPreProcess($content, $conf, $this);
1706 if (!isset($conf[
'cache.'])) {
1710 return $result ===
false ? $content : $result;
1722 $tags = isset($conf[
'addPageCacheTags.'])
1723 ? $this->
stdWrap($conf[
'addPageCacheTags'], $conf[
'addPageCacheTags.'])
1724 : $conf[
'addPageCacheTags'];
1725 if (!empty($tags)) {
1726 $cacheTags = GeneralUtility::trimExplode(
',', $tags,
true);
1769 $request =
$GLOBALS[
'TYPO3_REQUEST'] ??
null;
1770 $siteLanguage = $request ? $request->getAttribute(
'language') :
null;
1771 if ($siteLanguage instanceof SiteLanguage) {
1772 $currentLanguageCode = $siteLanguage->getTypo3Language();
1775 $currentLanguageCode = $tsfe->config[
'config'][
'language'] ??
null;
1777 if ($currentLanguageCode && isset($conf[
'lang.'][$currentLanguageCode])) {
1778 $content = $conf[
'lang.'][$currentLanguageCode];
1793 $content = $this->
getData($conf[
'data'], is_array($this->alternativeData) ? $this->alternativeData : $this->data);
1795 $this->alternativeData =
'';
1837 return $this->
cObjGetSingle($conf[
'cObject'] ??
'', $conf[
'cObject.'] ?? [],
'/stdWrap/.cObject');
1851 return $this->
numRows($conf[
'numRows.']);
1865 return $this->
filelist($conf[
'filelist'],
true);
1878 return $this->
callUserFunction($conf[
'preUserFunc'], $conf[
'preUserFunc.'], $content);
1892 foreach ($this->stdWrapHookObjects as $hookObject) {
1894 $content = $hookObject->stdWrapOverride($content, $conf, $this);
1909 if (trim($conf[
'override'] ??
false)) {
1910 $content = $conf[
'override'];
1926 return $this->
listNum($content, $conf[
'preIfEmptyListNum'] ??
null, $conf[
'preIfEmptyListNum.'][
'splitChar'] ??
null);
1939 return $content ?? $conf[
'ifNull'];
1953 if (!trim($content)) {
1954 $content = $conf[
'ifEmpty'];
1970 if (trim($content) ===
'') {
1971 $content = $conf[
'ifBlank'];
1988 return $this->
listNum($content, $conf[
'listNum'] ??
null, $conf[
'listNum.'][
'splitChar'] ??
null);
2000 return trim($content);
2018 $padType = STR_PAD_RIGHT;
2019 if (!empty($conf[
'strPad.'][
'length'])) {
2020 $length = isset($conf[
'strPad.'][
'length.']) ? $this->
stdWrap($conf[
'strPad.'][
'length'], $conf[
'strPad.'][
'length.']) : $conf[
'strPad.'][
'length'];
2021 $length = (int)$length;
2023 if (isset($conf[
'strPad.'][
'padWith']) && (string)$conf[
'strPad.'][
'padWith'] !==
'') {
2024 $padWith = isset($conf[
'strPad.'][
'padWith.']) ? $this->
stdWrap($conf[
'strPad.'][
'padWith'], $conf[
'strPad.'][
'padWith.']) : $conf[
'strPad.'][
'padWith'];
2026 if (!empty($conf[
'strPad.'][
'type'])) {
2027 $type = isset($conf[
'strPad.'][
'type.']) ? $this->
stdWrap($conf[
'strPad.'][
'type'], $conf[
'strPad.'][
'type.']) : $conf[
'strPad.'][
'type'];
2028 if (strtolower($type) ===
'left') {
2029 $padType = STR_PAD_LEFT;
2030 } elseif (strtolower($type) ===
'both') {
2031 $padType = STR_PAD_BOTH;
2034 return str_pad($content, $length, $padWith, $padType);
2050 return $this->
stdWrap($content, $conf[
'stdWrap.']);
2064 foreach ($this->stdWrapHookObjects as $hookObject) {
2066 $content = $hookObject->stdWrapProcess($content, $conf, $this);
2081 if ((
string)$content ===
'') {
2097 public function stdWrap_if($content =
'', $conf = [])
2099 if (empty($conf[
'if.']) || $this->
checkIf($conf[
'if.'])) {
2117 if (!trim($this->data[$conf[
'fieldRequired'] ??
null] ??
'')) {
2136 if (!empty($conf[
'csConv'])) {
2137 $output = mb_convert_encoding($content,
'utf-8', trim(strtolower($conf[
'csConv'])));
2154 return $this->
parseFunc($content, $conf[
'parseFunc.'], $conf[
'parseFunc']);
2168 if (isset($conf[
'HTMLparser.']) && is_array($conf[
'HTMLparser.'])) {
2185 return $this->
splitObj($content, $conf[
'split.']);
2198 return $this->
replacement($content, $conf[
'replacement.']);
2213 if (!empty($conf[
'prioriCalc']) && $conf[
'prioriCalc'] ===
'intval') {
2214 $content = (int)$content;
2232 return chr((
int)$conf[
'char']);
2244 return (
int)$content;
2255 public function stdWrap_hash($content =
'', array $conf = [])
2257 $algorithm = isset($conf[
'hash.']) ? $this->
stdWrap($conf[
'hash'], $conf[
'hash.']) : $conf[
'hash'];
2258 if (function_exists(
'hash') && in_array($algorithm, hash_algos())) {
2259 return hash($algorithm, $content);
2275 return $this->
round($content, $conf[
'round.']);
2288 return $this->
numberFormat($content, $conf[
'numberFormat.'] ?? []);
2300 return GeneralUtility::expandList($content);
2315 $content = (string)$content ===
'' ?
$GLOBALS[
'EXEC_TIME'] : (
int)$content;
2316 $content = !empty($conf[
'date.'][
'GMT']) ? gmdate($conf[
'date'] ??
null, $content) : date($conf[
'date'] ??
null, $content);
2332 $content = (string)$content ===
'' ?
$GLOBALS[
'EXEC_TIME'] : (
int)$content;
2333 $content = (isset($conf[
'strftime.'][
'GMT']) && $conf[
'strftime.'][
'GMT'])
2334 ? gmstrftime($conf[
'strftime'] ??
null, $content)
2335 : strftime($conf[
'strftime'] ??
null, $content);
2336 if (!empty($conf[
'strftime.'][
'charset'])) {
2337 $output = mb_convert_encoding($content,
'utf-8', trim(strtolower($conf[
'strftime.'][
'charset'])));
2353 if ($conf[
'strtotime'] !==
'1') {
2354 $content .=
' ' . $conf[
'strtotime'];
2356 return strtotime($content,
$GLOBALS[
'EXEC_TIME']);
2369 return $this->
calcAge((
int)(
$GLOBALS[
'EXEC_TIME'] ?? 0) - (
int)$content, $conf[
'age'] ??
null);
2396 return GeneralUtility::formatSize($content, $conf[
'bytes.'][
'labels'], $conf[
'bytes.'][
'base']);
2409 return $this->
substring($content, $conf[
'substring']);
2422 return $this->
cropHTML($content, $conf[
'cropHTML'] ??
'');
2434 return strip_tags($content);
2447 return $this->
crop($content, $conf[
'crop']);
2459 return rawurlencode($content);
2473 if (!empty($conf[
'htmlSpecialChars.'][
'preserveEntities'])) {
2474 $content = htmlspecialchars($content, ENT_COMPAT,
'UTF-8',
false);
2476 $content = htmlspecialchars($content);
2490 return GeneralUtility::quoteJSvalue($content);
2503 return preg_replace(
'/\R{1,2}[\t\x20]*\R{1,2}/', $conf[
'doubleBrTag'] ??
null, $content);
2529 return str_replace(LF, $conf[
'brTag'] ??
null, $content);
2569 return $this->
wrap($content, $conf[
'innerWrap'] ??
null);
2583 return $this->
wrap($content, $conf[
'innerWrap2'] ??
null);
2597 return $this->
addParams($content, $conf[
'addParams.'] ?? [],
true);
2612 return $this->
filelink($content, $conf[
'filelink.'] ?? [],
true);
2625 return $this->
cObjGetSingle($conf[
'preCObject'], $conf[
'preCObject.'],
'/stdWrap/.preCObject') . $content;
2638 return $content . $this->
cObjGetSingle($conf[
'postCObject'], $conf[
'postCObject.'],
'/stdWrap/.postCObject');
2652 $wrapAlign = trim($conf[
'wrapAlign'] ??
'');
2654 $content = $this->
wrap($content,
'<div style="text-align:' . htmlspecialchars($wrapAlign) .
';">|</div>');
2671 return $this->
typoLink($content, $conf[
'typolink.']);
2688 return $this->
wrap(
2690 $conf[
'wrap'] ??
null,
2691 $conf[
'wrap.'][
'splitChar'] ??
'|'
2706 $splitChar = isset($conf[
'noTrimWrap.'][
'splitChar.'])
2707 ? $this->
stdWrap($conf[
'noTrimWrap.'][
'splitChar'] ??
'', $conf[
'noTrimWrap.'][
'splitChar.'])
2708 : $conf[
'noTrimWrap.'][
'splitChar'] ??
'';
2709 if ($splitChar ===
null || $splitChar ===
'') {
2714 $conf[
'noTrimWrap'],
2731 return $this->
wrap(
2733 $conf[
'wrap2'] ??
null,
2734 $conf[
'wrap2.'][
'splitChar'] ??
'|'
2749 return $this->
dataWrap($content, $conf[
'dataWrap']);
2762 return $this->
cObjGetSingle($conf[
'prepend'], $conf[
'prepend.'],
'/stdWrap/.prepend') . $content;
2775 return $content . $this->
cObjGetSingle($conf[
'append'], $conf[
'append.'],
'/stdWrap/.append');
2789 return $this->
wrap(
2791 $conf[
'wrap3'] ??
null,
2792 $conf[
'wrap3.'][
'splitChar'] ??
'|'
2807 foreach ($sortedKeysArray as $key) {
2808 $content = $this->
stdWrap($content, $conf[
'orderedStdWrap.'][$key .
'.'] ??
null);
2823 return $this->
wrap($content, $conf[
'outerWrap'] ??
null);
2848 return $this->
callUserFunction($conf[
'postUserFunc'], $conf[
'postUserFunc.'], $content);
2864 'content' => $content,
2865 'postUserFunc' => $conf[
'postUserFuncInt'],
2866 'conf' => $conf[
'postUserFuncInt.'],
2867 'type' =>
'POSTUSERFUNC',
2868 'cObj' => serialize($this)
2870 $content =
'<!--' . $substKey .
'-->';
2886 && !empty($conf[
'prefixComment'])
2888 $content = $this->
prefixComment($conf[
'prefixComment'], [], $content);
2904 if (!isset($conf[
'editIcons.']) || !is_array($conf[
'editIcons.'])) {
2905 $conf[
'editIcons.'] = [];
2907 $content = $this->
editIcons($content, $conf[
'editIcons'], $conf[
'editIcons.']);
2923 $content = $this->
editPanel($content, $conf[
'editPanel.']);
2930 $build = $conf[
'build'] ??
'default';
2931 if (class_exists($build) && is_a($build, BuilderInterface::class,
true)) {
2932 $builder = GeneralUtility::makeInstance($build);
2934 $factory = GeneralUtility::makeInstance(SanitizerBuilderFactory::class);
2935 $builder = $factory->build($build);
2937 $sanitizer = $builder->build();
2941 return $sanitizer->sanitize($content, $initiator);
2953 if (!isset($conf[
'cache.'])) {
2961 $cacheFrontend = GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_hash');
2964 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'stdWrap_cacheStore'] ?? [] as $_funcRef) {
2967 'content' => $content,
2968 'lifetime' => $lifetime,
2971 GeneralUtility::callUserFunction($_funcRef, $params, $this);
2973 $cacheFrontend->set($key, $content, $tags, $lifetime);
2988 foreach ($this->stdWrapHookObjects as $hookObject) {
2990 $content = $hookObject->stdWrapPostProcess($content, $conf, $this);
3004 return '<pre>' . htmlspecialchars($content) .
'</pre>';
3017 debug((
int)$conf[
'debugFunc'] === 2 ? [$content] : $content);
3030 debug($this->data,
'$cObj->data:');
3031 if (is_array($this->alternativeData)) {
3032 debug($this->alternativeData,
'$this->alternativeData');
3048 $conf[
'select.'][
'selectFields'] =
'count(*)';
3049 $statement = $this->
exec_getQuery($conf[
'table'], $conf[
'select.']);
3051 return (
int)$statement->fetchColumn(0);
3062 public function listNum($content, $listNum, $char)
3064 $char = $char ?:
',';
3068 $temp = explode($char, $content);
3069 $last =
'' . (count($temp) - 1);
3071 if ($listNum ===
'rand') {
3072 $listNum = rand(0, count($temp) - 1);
3074 $index = $this->
calc(str_ireplace(
'last', $last, $listNum));
3075 return $temp[$index];
3088 if (!is_array($conf)) {
3091 if (isset($conf[
'directReturn'])) {
3092 return (
bool)$conf[
'directReturn'];
3095 if (isset($conf[
'isNull.'])) {
3096 $isNull = $this->
stdWrap(
'', $conf[
'isNull.']);
3097 if ($isNull !==
null) {
3101 if (isset($conf[
'isTrue']) || isset($conf[
'isTrue.'])) {
3102 $isTrue = isset($conf[
'isTrue.']) ? trim($this->
stdWrap($conf[
'isTrue'], $conf[
'isTrue.'])) : trim($conf[
'isTrue']);
3107 if (isset($conf[
'isFalse']) || isset($conf[
'isFalse.'])) {
3108 $isFalse = isset($conf[
'isFalse.']) ? trim($this->
stdWrap($conf[
'isFalse'], $conf[
'isFalse.'])) : trim($conf[
'isFalse']);
3113 if (isset($conf[
'isPositive']) || isset($conf[
'isPositive.'])) {
3114 $number = isset($conf[
'isPositive.']) ? $this->
calc($this->
stdWrap($conf[
'isPositive'], $conf[
'isPositive.'])) : $this->
calc($conf[
'isPositive']);
3120 $value = isset($conf[
'value.'])
3121 ? trim($this->
stdWrap($conf[
'value'] ??
'', $conf[
'value.']))
3122 : trim($conf[
'value'] ??
'');
3123 if (isset($conf[
'isGreaterThan']) || isset($conf[
'isGreaterThan.'])) {
3124 $number = isset($conf[
'isGreaterThan.']) ? trim($this->
stdWrap($conf[
'isGreaterThan'], $conf[
'isGreaterThan.'])) : trim($conf[
'isGreaterThan']);
3125 if ($number <= $value) {
3129 if (isset($conf[
'isLessThan']) || isset($conf[
'isLessThan.'])) {
3130 $number = isset($conf[
'isLessThan.']) ? trim($this->
stdWrap($conf[
'isLessThan'], $conf[
'isLessThan.'])) : trim($conf[
'isLessThan']);
3131 if ($number >= $value) {
3135 if (isset($conf[
'equals']) || isset($conf[
'equals.'])) {
3136 $number = isset($conf[
'equals.']) ? trim($this->
stdWrap($conf[
'equals'], $conf[
'equals.'])) : trim($conf[
'equals']);
3137 if ($number != $value) {
3141 if (isset($conf[
'isInList']) || isset($conf[
'isInList.'])) {
3142 $number = isset($conf[
'isInList.']) ? trim($this->
stdWrap($conf[
'isInList'], $conf[
'isInList.'])) : trim($conf[
'isInList']);
3143 if (!GeneralUtility::inList($value, $number)) {
3148 if ($conf[
'negate'] ??
false) {
3168 trigger_error(
'ContentObjectRenderer->filelist() will be removed in TYPO3 v10.0. Use cObject FILES instead.', E_USER_DEPRECATED);
3174 list($possiblePath, $ext_list, $sorting, $reverse, $useFullPath) = GeneralUtility::trimExplode(
'|',
$data);
3179 if (GeneralUtility::validPathStr($possiblePath)) {
3181 $possiblePath = preg_replace(
'/[\\/\\. ]*$/',
'', $possiblePath);
3182 if (!GeneralUtility::isAbsPath($possiblePath) && @is_dir($possiblePath)) {
3184 $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
3185 $storages = $storageRepository->findAll();
3186 foreach ($storages as $storage) {
3187 if ($storage->getDriverType() ===
'Local' && $storage->isPublic() && $storage->isOnline()) {
3188 $folder = $storage->getPublicUrl($storage->getRootLevelFolder(),
true);
3189 if (GeneralUtility::isFirstPartOfStr($possiblePath .
'/', $folder)) {
3190 $path = $possiblePath;
3204 $ext_list = strtolower(GeneralUtility::uniqueList($ext_list));
3207 if (is_object($d)) {
3209 while ($entry = $d->read()) {
3210 if ($entry !==
'.' && $entry !==
'..') {
3212 $wholePath = $path .
'/' . $entry;
3213 if (file_exists($wholePath) && filetype($wholePath) ===
'file') {
3214 $info = GeneralUtility::split_fileref($wholePath);
3215 if (!$ext_list || GeneralUtility::inList($ext_list, $info[
'fileext'])) {
3216 $items[
'files'][] = $info[
'file'];
3219 $items[
'sorting'][] = strtolower($info[
'file']);
3222 $items[
'sorting'][] = filesize($wholePath);
3225 $items[
'sorting'][] = $info[
'fileext'];
3228 $items[
'sorting'][] = filectime($wholePath);
3231 $items[
'sorting'][] = filemtime($wholePath);
3234 $items[
'sorting'][] = $count;
3244 if (!empty($items[
'sorting'])) {
3245 if (strtolower($reverse) !==
'r') {
3246 asort($items[
'sorting']);
3248 arsort($items[
'sorting']);
3251 if (!empty($items[
'files'])) {
3253 reset($items[
'sorting']);
3255 foreach ($items[
'sorting'] as $key => $v) {
3256 $list_arr[] = $useFullPath ? $path .
'/' . $items[
'files'][$key] : $items[
'files'][$key];
3258 return implode(
',', $list_arr);
3275 $htmlParser = GeneralUtility::makeInstance(HtmlParser::class);
3276 $htmlParserCfg = $htmlParser->HTMLparserConfig($conf);
3277 return $htmlParser->HTMLcleaner($theValue, $htmlParserCfg[0], $htmlParserCfg[1], $htmlParserCfg[2], $htmlParserCfg[3]);
3288 public function dataWrap($content, $wrap)
3311 $totalLen = strlen($str);
3314 $len = strcspn(substr($str, $pointer),
'{');
3315 $newVal .= substr($str, $pointer, $len);
3317 if (substr($str, $pointer + $len + 1, 1) ===
'#') {
3318 $len2 = strcspn(substr($str, $pointer + $len),
'}');
3319 $newVal .= substr($str, $pointer + $len, $len2);
3324 $len = strcspn(substr($str, $pointer),
'}') + 1;
3325 $newVal .= $this->
getData(substr($str, $pointer + 1, $len - 2), $this->data);
3329 }
while ($pointer < $totalLen);
3348 $parts = explode(
'|', $str);
3349 $indent = (int)$parts[0];
3350 $comment = htmlspecialchars($this->
insertData($parts[1]));
3352 . str_pad(
'', $indent,
"\t") .
'<!-- ' . $comment .
' [begin] -->' . LF
3353 . str_pad(
'', $indent + 1,
"\t") . $content . LF
3354 . str_pad(
'', $indent,
"\t") .
'<!-- ' . $comment .
' [end] -->' . LF
3355 . str_pad(
'', $indent + 1,
"\t");
3368 public function substring($content, $options)
3370 $options = GeneralUtility::intExplode(
',', $options .
',');
3372 return mb_substr($content, $options[0], $options[1],
'utf-8');
3374 return mb_substr($content, $options[0],
null,
'utf-8');
3386 public function crop($content, $options)
3388 $options = explode(
'|', $options);
3389 $chars = (int)$options[0];
3390 $afterstring = trim($options[1] ??
'');
3391 $crop2space = trim($options[2] ??
'');
3393 if (mb_strlen($content,
'utf-8') > abs($chars)) {
3394 $truncatePosition =
false;
3396 $content = mb_substr($content, $chars,
null,
'utf-8');
3398 $truncatePosition = strpos($content,
' ');
3400 $content = $truncatePosition ? $afterstring . substr($content, $truncatePosition) : $afterstring . $content;
3402 $content = mb_substr($content, 0, $chars,
'utf-8');
3404 $truncatePosition = strrpos($content,
' ');
3406 $content = $truncatePosition ? substr($content, 0, $truncatePosition) . $afterstring : $content . $afterstring;
3426 public function cropHTML($content, $options)
3428 $options = explode(
'|', $options);
3429 $chars = (int)$options[0];
3430 $absChars = abs($chars);
3431 $replacementForEllipsis = trim($options[1] ??
'');
3432 $crop2space = trim($options[2] ??
'') ===
'1';
3434 $tags =
'a|abbr|address|area|article|aside|audio|b|bdi|bdo|blockquote|body|br|button|caption|cite|code|col|colgroup|data|datalist|dd|del|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|h1|h2|h3|h4|h5|h6|header|hr|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|main|map|mark|meter|nav|object|ol|optgroup|option|output|p|param|pre|progress|q|rb|rp|rt|rtc|ruby|s|samp|section|select|small|source|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|tr|track|u|ul|ut|var|video|wbr';
3438 <!--.*?--> # a comment
3440 <canvas[^>]*>.*?</canvas> # a canvas tag
3442 <script[^>]*>.*?</script> # a script tag
3444 <noscript[^>]*>.*?</noscript> # a noscript tag
3446 <template[^>]*>.*?</template> # a template tag
3449 </?(?:' . $tags .
')+ # opening tag (\'<tag\') or closing tag (\'</tag\')
3453 \\s+\\w[\\w-]* # EITHER spaces, followed by attribute names
3457 ".*?" # attribute values in double-quotes
3459 \'.*?\' # attribute values in single-quotes
3461 [^\'">\\s]+ # plain attribute values
3465 | # OR a single dash (for TYPO3 link tag)
3473 /?> # closing the tag with \'>\' or \'/>\'
3475 $splittedContent = preg_split(
'%' . $tagsRegEx .
'%xs', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
3478 $splittedContent = array_reverse($splittedContent);
3483 $croppedOffset =
null;
3484 $countSplittedContent = count($splittedContent);
3485 for ($offset = 0; $offset < $countSplittedContent; $offset++) {
3486 if ($offset % 2 === 0) {
3487 $tempContent = $splittedContent[$offset];
3488 $thisStrLen = mb_strlen(html_entity_decode($tempContent, ENT_COMPAT,
'UTF-8'),
'utf-8');
3489 if ($strLen + $thisStrLen > $absChars) {
3490 $croppedOffset = $offset;
3491 $cropPosition = $absChars - $strLen;
3493 $patternMatchEntityAsSingleChar =
'(&[^&\\s;]{2,8};|.)';
3494 $cropRegEx = $chars < 0 ?
'#' . $patternMatchEntityAsSingleChar .
'{0,' . ($cropPosition + 1) .
'}$#uis' :
'#^' . $patternMatchEntityAsSingleChar .
'{0,' . ($cropPosition + 1) .
'}#uis';
3495 if (preg_match($cropRegEx, $tempContent, $croppedMatch)) {
3496 $tempContentPlusOneCharacter = $croppedMatch[0];
3498 $tempContentPlusOneCharacter =
false;
3500 $cropRegEx = $chars < 0 ?
'#' . $patternMatchEntityAsSingleChar .
'{0,' . $cropPosition .
'}$#uis' :
'#^' . $patternMatchEntityAsSingleChar .
'{0,' . $cropPosition .
'}#uis';
3501 if (preg_match($cropRegEx, $tempContent, $croppedMatch)) {
3502 $tempContent = $croppedMatch[0];
3503 if ($crop2space && $tempContentPlusOneCharacter !==
false) {
3504 $cropRegEx = $chars < 0 ?
'#(?<=\\s)' . $patternMatchEntityAsSingleChar .
'{0,' . $cropPosition .
'}$#uis' :
'#^' . $patternMatchEntityAsSingleChar .
'{0,' . $cropPosition .
'}(?=\\s)#uis';
3505 if (preg_match($cropRegEx, $tempContentPlusOneCharacter, $croppedMatch)) {
3506 $tempContent = $croppedMatch[0];
3510 $splittedContent[$offset] = $tempContent;
3513 $strLen += $thisStrLen;
3518 if ($croppedOffset !==
null) {
3519 $openingTagRegEx =
'#^<(\\w+)(?:\\s|>)#';
3520 $closingTagRegEx =
'#^</(\\w+)(?:\\s|>)#';
3521 for ($offset = $croppedOffset - 1; $offset >= 0; $offset = $offset - 2) {
3522 if (substr($splittedContent[$offset], -2) ===
'/>') {
3526 preg_match($chars < 0 ? $closingTagRegEx : $openingTagRegEx, $splittedContent[$offset], $matches);
3527 $tagName = $matches[1] ??
null;
3528 if ($tagName !==
null) {
3530 $countSplittedContent = count($splittedContent);
3531 for ($seekingOffset = $offset + 2; $seekingOffset < $countSplittedContent; $seekingOffset = $seekingOffset + 2) {
3532 preg_match($chars < 0 ? $openingTagRegEx : $closingTagRegEx, $splittedContent[$seekingOffset], $matches);
3533 $seekingTagName = $matches[1] ??
null;
3534 if ($tagName === $seekingTagName) {
3537 if ($seekingOffset > $croppedOffset) {
3538 $closingTags[] = $splittedContent[$seekingOffset];
3546 array_splice($splittedContent, $croppedOffset + 1);
3548 $splittedContent = array_merge($splittedContent, [
3549 $croppedOffset !==
null ? $replacementForEllipsis :
''
3553 $splittedContent = array_reverse($splittedContent);
3555 return implode(
'', $splittedContent);
3568 public function addParams($content, $conf, $isCoreCall =
false)
3571 trigger_error(
'ContentObjectRenderer->addParams() will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
3574 $lowerCaseAttributes =
true;
3575 if (!is_array($conf)) {
3579 $parts = explode(
'<', $content);
3580 if (isset($conf[
'_offset']) && (
int)$conf[
'_offset']) {
3581 $key = (int)$conf[
'_offset'] < 0 ? count($parts) + (int)$conf[
'_offset'] : (
int)$conf[
'_offset'];
3583 $subparts = explode(
'>', $parts[$key] ??
'');
3584 if (trim($subparts[0])) {
3586 $attribs = GeneralUtility::get_tag_attributes(
'<' . $subparts[0] .
'>');
3587 list($tagName) = explode(
' ', $subparts[0], 2);
3589 foreach ($conf as $pkey => $val) {
3590 if (substr($pkey, -1) !==
'.' && $pkey[0] !==
'_') {
3591 $tmpVal = isset($conf[$pkey .
'.']) ? $this->
stdWrap($conf[$pkey], $conf[$pkey .
'.']) : (string)$val;
3592 if ($lowerCaseAttributes) {
3593 $pkey = strtolower($pkey);
3595 if ($tmpVal !==
'') {
3596 $attribs[$pkey] = $tmpVal;
3601 $subparts[0] = trim($tagName .
' ' . GeneralUtility::implodeAttributes($attribs));
3602 $parts[$key] = implode(
'>', $subparts);
3603 $content = implode(
'<', $parts);
3620 public function filelink($theValue, $conf, $isCoreCall =
false)
3623 trigger_error(
'ContentObjectRenderer->filelink() will be removed in TYPO3 v10.0. Use cObject FILES instead.', E_USER_DEPRECATED);
3625 $conf[
'path'] = isset($conf[
'path.'])
3626 ? $this->
stdWrap($conf[
'path'] ??
'', $conf[
'path.'])
3627 : ($conf[
'path'] ??
'');
3628 $theFile = trim($conf[
'path']) . $theValue;
3629 if (!@is_file($theFile)) {
3632 $theFileEnc = str_replace(
'%2F',
'/', rawurlencode($theFile));
3633 $title = $conf[
'title'] ??
'';
3634 if (isset($conf[
'title.'])) {
3635 $title = $this->
stdWrap($title, $conf[
'title.']);
3637 $target = $conf[
'target'] ??
'';
3638 if (isset($conf[
'target.'])) {
3639 $target = $this->
stdWrap($target, $conf[
'target.']);
3644 'parameter' => $theFileEnc,
3645 'fileTarget' => $target,
3650 if (isset($conf[
'typolinkConfiguration.'])) {
3651 $additionalTypoLinkConfiguration = $conf[
'typolinkConfiguration.'];
3654 $typoLinkConf = $additionalTypoLinkConfiguration;
3657 $theLinkWrap = $this->
typoLink(
'|', $typoLinkConf);
3658 $theSize = filesize($theFile);
3659 $fI = GeneralUtility::split_fileref($theFile);
3661 if ($conf[
'icon'] ??
false) {
3662 $conf[
'icon.'][
'path'] = isset($conf[
'icon.'][
'path.'])
3663 ? $this->
stdWrap($conf[
'icon.'][
'path'], $conf[
'icon.'][
'path.'])
3664 : $conf[
'icon.'][
'path'];
3665 $iconPath = !empty($conf[
'icon.'][
'path'])
3666 ? $conf[
'icon.'][
'path']
3667 : GeneralUtility::getFileAbsFileName(
'EXT:frontend/Resources/Public/Icons/FileIcons/');
3668 $conf[
'icon.'][
'ext'] = isset($conf[
'icon.'][
'ext.'])
3669 ? $this->
stdWrap($conf[
'icon.'][
'ext'], $conf[
'icon.'][
'ext.'])
3670 : $conf[
'icon.'][
'ext'];
3671 $iconExt = !empty($conf[
'icon.'][
'ext']) ?
'.' . $conf[
'icon.'][
'ext'] :
'.gif';
3672 $icon = @is_file($iconPath . $fI[
'fileext'] . $iconExt)
3673 ? $iconPath . $fI[
'fileext'] . $iconExt
3674 : $iconPath .
'default' . $iconExt;
3677 $IEList = isset($conf[
'icon_image_ext_list.']) ? $this->
stdWrap($conf[
'icon_image_ext_list'], $conf[
'icon_image_ext_list.']) : $conf[
'icon_image_ext_list'];
3678 $image_ext_list = str_replace(
' ',
'', strtolower($IEList));
3679 if ($fI[
'fileext'] && GeneralUtility::inList($image_ext_list, $fI[
'fileext'])) {
3680 if ($conf[
'iconCObject']) {
3681 $icon = $this->
cObjGetSingle($conf[
'iconCObject'], $conf[
'iconCObject.'],
'iconCObject');
3683 $notFoundThumb = GeneralUtility::getFileAbsFileName(
'EXT:core/Resources/Public/Images/NotFound.gif');
3685 $sizeParts = [64, 64];
3686 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'thumbnails']) {
3691 if ($fileObject->isMissing()) {
3692 $icon = $notFoundThumb;
3695 if ($fileExtension ===
'ttf' || GeneralUtility::inList(
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'imagefile_ext'], $fileExtension)) {
3696 if ($conf[
'icon_thumbSize'] || $conf[
'icon_thumbSize.']) {
3697 $thumbSize = isset($conf[
'icon_thumbSize.']) ? $this->
stdWrap($conf[
'icon_thumbSize'], $conf[
'icon_thumbSize.']) : $conf[
'icon_thumbSize'];
3698 $sizeParts = explode(
'x', $thumbSize);
3701 'width' => $sizeParts[0],
3702 'height' => $sizeParts[1]
3703 ])->getPublicUrl(
true);
3706 }
catch (ResourceDoesNotExistException $exception) {
3707 $icon = $notFoundThumb;
3710 $icon = $notFoundThumb;
3713 if (parse_url($icon, PHP_URL_HOST) ===
null) {
3714 $urlPrefix = $tsfe->absRefPrefix;
3716 $icon =
'<img src="' . htmlspecialchars($urlPrefix . $icon) .
'"' .
3717 ' width="' . (int)$sizeParts[0] .
'" height="' . (
int)$sizeParts[1] .
'" ' .
3721 $conf[
'icon.'][
'widthAttribute'] = isset($conf[
'icon.'][
'widthAttribute.'])
3722 ? $this->
stdWrap($conf[
'icon.'][
'widthAttribute'], $conf[
'icon.'][
'widthAttribute.'])
3723 : $conf[
'icon.'][
'widthAttribute'];
3724 $iconWidth = !empty($conf[
'icon.'][
'widthAttribute']) ? $conf[
'icon.'][
'widthAttribute'] : 18;
3725 $conf[
'icon.'][
'heightAttribute'] = isset($conf[
'icon.'][
'heightAttribute.'])
3726 ? $this->
stdWrap($conf[
'icon.'][
'heightAttribute'], $conf[
'icon.'][
'heightAttribute.'])
3727 : $conf[
'icon.'][
'heightAttribute'];
3728 $iconHeight = !empty($conf[
'icon.'][
'heightAttribute']) ? (int)$conf[
'icon.'][
'heightAttribute'] : 16;
3729 $icon =
'<img src="' . htmlspecialchars($tsfe->absRefPrefix . $icon) .
'" width="' . (int)$iconWidth .
'" height="' . (
int)$iconHeight .
'"'
3732 if ($conf[
'icon_link'] && !$conf[
'combinedLink']) {
3733 $icon = $this->
wrap($icon, $theLinkWrap);
3735 $icon = isset($conf[
'icon.']) ? $this->
stdWrap($icon, $conf[
'icon.']) : $icon;
3738 if ($conf[
'size'] ??
false) {
3739 $size = isset($conf[
'size.']) ? $this->
stdWrap($theSize, $conf[
'size.']) : $theSize;
3742 if ($conf[
'removePrependedNumbers'] ??
false) {
3743 $theValue = preg_replace(
'/_[0-9][0-9](\\.[[:alnum:]]*)$/',
'\\1', $theValue);
3745 if (isset($conf[
'labelStdWrap.'])) {
3746 $theValue = $this->
stdWrap($theValue, $conf[
'labelStdWrap.']);
3749 $wrap = isset($conf[
'wrap.'])
3750 ? $this->
stdWrap($conf[
'wrap'] ??
'', $conf[
'wrap.'])
3751 : ($conf[
'wrap'] ??
'');
3752 if ($conf[
'combinedLink'] ??
false) {
3753 $theValue = $icon . $theValue;
3754 if ($conf[
'ATagBeforeWrap']) {
3755 $theValue = $this->
wrap($this->
wrap($theValue, $wrap), $theLinkWrap);
3757 $theValue = $this->
wrap($this->
wrap($theValue, $theLinkWrap), $wrap);
3759 $file = isset($conf[
'file.']) ? $this->
stdWrap($theValue, $conf[
'file.']) : $theValue;
3763 if ($conf[
'ATagBeforeWrap'] ??
false) {
3764 $theValue = $this->
wrap($this->
wrap($theValue, $wrap), $theLinkWrap);
3766 $theValue = $this->
wrap($this->
wrap($theValue, $theLinkWrap), $wrap);
3768 $file = isset($conf[
'file.']) ? $this->
stdWrap($theValue, $conf[
'file.']) : $theValue;
3772 if (isset($conf[
'stdWrap.'])) {
3785 public function calc($val)
3787 $parts = GeneralUtility::splitCalc($val,
'+-*/');
3789 foreach ($parts as $part) {
3792 if ((
string)(
int)$theVal === (
string)$theVal) {
3793 $theVal = (int)$theVal;
3797 if ($sign ===
'-') {
3800 if ($sign ===
'+') {
3803 if ($sign ===
'/') {
3805 $value /= (int)$theVal;
3808 if ($sign ===
'*') {
3827 trigger_error(
'calcIntExplode will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
3828 $temp = explode($delim, $string);
3829 foreach ($temp as $key => $val) {
3830 $temp[$key] = (int)$this->
calc($val);
3846 public function splitObj($value, $conf)
3848 $conf[
'token'] = isset($conf[
'token.']) ? $this->
stdWrap($conf[
'token'], $conf[
'token.']) : $conf[
'token'];
3849 if ($conf[
'token'] ===
'') {
3852 $valArr = explode($conf[
'token'], $value);
3857 $key = isset($conf[
'returnKey.']) ? (int)$this->
stdWrap($conf[
'returnKey'], $conf[
'returnKey.']) : (int)$conf[
'returnKey'];
3858 return $valArr[$key] ??
'';
3862 if (!empty($valArr) && ($conf[
'returnCount'] || $conf[
'returnCount.'])) {
3863 $returnCount = isset($conf[
'returnCount.']) ? (bool)$this->
stdWrap($conf[
'returnCount'], $conf[
'returnCount.']) : (bool)$conf[
'returnCount'];
3864 return $returnCount ? count($valArr) : 0;
3868 $splitCount = count($valArr);
3869 $max = isset($conf[
'max.']) ? (int)$this->
stdWrap($conf[
'max'], $conf[
'max.']) : (int)$conf[
'max'];
3870 if ($max && $splitCount > $max) {
3873 $min = isset($conf[
'min.']) ? (int)$this->
stdWrap($conf[
'min'], $conf[
'min.']) : (int)$conf[
'min'];
3874 if ($min && $splitCount < $min) {
3877 $wrap = isset($conf[
'wrap.']) ? (string)$this->
stdWrap($conf[
'wrap'], $conf[
'wrap.']) : (string)$conf[
'wrap'];
3878 $cObjNumSplitConf = isset($conf[
'cObjNum.']) ? (string)$this->
stdWrap($conf[
'cObjNum'], $conf[
'cObjNum.']) : (string)$conf[
'cObjNum'];
3880 if ($wrap !==
'' || $cObjNumSplitConf !==
'') {
3881 $splitArr[
'wrap'] = $wrap;
3882 $splitArr[
'cObjNum'] = $cObjNumSplitConf;
3883 $splitArr = GeneralUtility::makeInstance(TypoScriptService::class)
3884 ->explodeConfigurationForOptionSplit($splitArr, $splitCount);
3887 for ($a = 0; $a < $splitCount; $a++) {
3889 $value =
'' . $valArr[$a];
3891 if ($splitArr[$a][
'cObjNum']) {
3892 $objName = (int)$splitArr[$a][
'cObjNum'];
3893 $value = isset($conf[$objName .
'.'])
3894 ? $this->
stdWrap($this->
cObjGet($conf[$objName .
'.'], $objName .
'.'), $conf[$objName .
'.'])
3895 : $this->
cObjGet($conf[$objName .
'.'], $objName .
'.');
3897 $wrap = isset($splitArr[$a][
'wrap.']) ? $this->
stdWrap($splitArr[$a][
'wrap'], $splitArr[$a][
'wrap.']) : $splitArr[$a][
'wrap'];
3899 $value = $this->
wrap($value, $wrap);
3913 protected function replacement($content, array $configuration)
3916 ksort($configuration, SORT_NUMERIC);
3917 foreach ($configuration as $index => $action) {
3935 if ((isset($configuration[
'search']) || isset($configuration[
'search.'])) && (isset($configuration[
'replace']) || isset($configuration[
'replace.']))) {
3937 $search = isset($configuration[
'search.']) ? $this->
stdWrap($configuration[
'search'], $configuration[
'search.']) : $configuration[
'search'];
3938 $replace = isset($configuration[
'replace.'])
3939 ? $this->
stdWrap($configuration[
'replace'] ??
null, $configuration[
'replace.'])
3940 : $configuration[
'replace'] ?? null;
3941 $useRegularExpression =
false;
3943 if (isset($configuration[
'useRegExp'])
3944 || (isset($configuration[
'useRegExp.']) && $configuration[
'useRegExp.'])
3946 $useRegularExpression = isset($configuration[
'useRegExp.']) ? (bool)$this->
stdWrap($configuration[
'useRegExp'], $configuration[
'useRegExp.']) : (bool)$configuration[
'useRegExp'];
3948 $useOptionSplitReplace =
false;
3950 if (isset($configuration[
'useOptionSplitReplace']) || isset($configuration[
'useOptionSplitReplace.'])) {
3951 $useOptionSplitReplace = isset($configuration[
'useOptionSplitReplace.']) ? (bool)$this->
stdWrap($configuration[
'useOptionSplitReplace'], $configuration[
'useOptionSplitReplace.']) : (bool)$configuration[
'useOptionSplitReplace'];
3955 if ($useRegularExpression) {
3957 $separator = $search[0];
3958 $startModifiers = strrpos($search, $separator);
3959 if ($separator !==
false && $startModifiers > 0) {
3960 $modifiers = substr($search, $startModifiers + 1);
3962 $modifiers = str_replace(
'e',
'', $modifiers);
3963 $search = substr($search, 0, $startModifiers + 1) . $modifiers;
3965 if ($useOptionSplitReplace) {
3967 $splitCount = preg_match_all($search, $content, $matches);
3968 $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
3969 $replaceArray = $typoScriptService->explodeConfigurationForOptionSplit([$replace], $splitCount);
3972 $replaceCallback =
function ($match) use ($replaceArray, $search, &$replaceCount) {
3974 return preg_replace($search, $replaceArray[$replaceCount - 1][0], $match[0]);
3976 $content = preg_replace_callback($search, $replaceCallback, $content);
3978 $content = preg_replace($search, $replace, $content);
3980 } elseif ($useOptionSplitReplace) {
3982 $searchPreg =
'#' . preg_quote($search,
'#') .
'#';
3985 $splitCount = preg_match_all($searchPreg, $content, $matches);
3986 $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
3987 $replaceArray = $typoScriptService->explodeConfigurationForOptionSplit([$replace], $splitCount);
3990 $replaceCallback =
function () use ($replaceArray, $search, &$replaceCount) {
3992 return $replaceArray[$replaceCount - 1][0];
3994 $content = preg_replace_callback($searchPreg, $replaceCallback, $content);
3996 $content = str_replace($search, $replace, $content);
4010 protected function round($content, array $conf = [])
4012 $decimals = isset($conf[
'decimals.'])
4013 ? $this->
stdWrap($conf[
'decimals'] ??
'', $conf[
'decimals.'])
4014 : ($conf[
'decimals'] ?? null);
4015 $type = isset($conf[
'roundType.'])
4016 ? $this->
stdWrap($conf[
'roundType'] ??
'', $conf[
'roundType.'])
4017 : ($conf[
'roundType'] ?? null);
4018 $floatVal = (float)$content;
4021 $content = ceil($floatVal);
4024 $content = floor($floatVal);
4029 $content =
round($floatVal, (
int)$decimals);
4044 $decimals = isset($conf[
'decimals.'])
4045 ? (int)$this->
stdWrap($conf[
'decimals'] ??
'', $conf[
'decimals.'])
4046 : (int)($conf[
'decimals'] ?? 0);
4047 $dec_point = isset($conf[
'dec_point.'])
4048 ? $this->
stdWrap($conf[
'dec_point'] ??
'', $conf[
'dec_point.'])
4049 : ($conf[
'dec_point'] ?? null);
4050 $thousands_sep = isset($conf[
'thousands_sep.'])
4051 ? $this->
stdWrap($conf[
'thousands_sep'] ??
'', $conf[
'thousands_sep.'])
4052 : ($conf[
'thousands_sep'] ?? null);
4053 return number_format((
float)$content, $decimals, $dec_point, $thousands_sep);
4075 public function parseFunc($theValue, $conf, $ref =
'')
4080 'parseFunc' => $ref,
4081 'parseFunc.' => $conf
4083 $temp_conf = $this->
mergeTSRef($temp_conf,
'parseFunc');
4084 $conf = $temp_conf[
'parseFunc.'];
4089 trigger_error(
'Invoking ContentObjectRenderer::parseFunc without any configuration will trigger an exception in TYPO3 v12.0', E_USER_DEPRECATED);
4093 if (!isset($conf[
'htmlSanitize'])) {
4095 trigger_error(
'Property htmlSanitize was not defined, but will be mandatory in TYPO3 v12.0', E_USER_DEPRECATED);
4096 $features = GeneralUtility::makeInstance(Features::class);
4097 $conf[
'htmlSanitize'] = $features->isFeatureEnabled(
'security.frontend.htmlSanitizeParseFuncDefault');
4099 $conf[
'htmlSanitize'] = (bool)$conf[
'htmlSanitize'];
4102 if ((
string)($conf[
'externalBlocks'] ??
'') ===
'') {
4104 if ($conf[
'htmlSanitize']) {
4109 $tags = strtolower(implode(
',', GeneralUtility::trimExplode(
',', $conf[
'externalBlocks'])));
4110 $htmlParser = GeneralUtility::makeInstance(HtmlParser::class);
4111 $parts = $htmlParser->splitIntoBlock($tags, $theValue);
4112 foreach ($parts as $k => $v) {
4115 $tagName = strtolower($htmlParser->getFirstTagName($v));
4116 $cfg = $conf[
'externalBlocks.'][$tagName .
'.'];
4117 if ($cfg[
'stripNLprev'] || $cfg[
'stripNL']) {
4118 $parts[$k - 1] = preg_replace(
'/' . CR .
'?' . LF .
'[ ]*$/',
'', $parts[$k - 1]);
4120 if ($cfg[
'stripNLnext'] || $cfg[
'stripNL']) {
4121 $parts[$k + 1] = preg_replace(
'/^[ ]*' . CR .
'?' . LF .
'/',
'', $parts[$k + 1]);
4125 foreach ($parts as $k => $v) {
4127 $tag = $htmlParser->getFirstTag($v);
4128 $tagName = strtolower($htmlParser->getFirstTagName($v));
4129 $cfg = $conf[
'externalBlocks.'][$tagName .
'.'];
4130 if ($cfg[
'callRecursive']) {
4131 $parts[$k] = $this->
parseFunc($htmlParser->removeFirstAndLastTag($v), $conf);
4132 if (!$cfg[
'callRecursive.'][
'dontWrapSelf']) {
4133 if ($cfg[
'callRecursive.'][
'alternativeWrap']) {
4134 $parts[$k] = $this->
wrap($parts[$k], $cfg[
'callRecursive.'][
'alternativeWrap']);
4136 if (is_array($cfg[
'callRecursive.'][
'tagStdWrap.'])) {
4137 $tag = $this->
stdWrap($tag, $cfg[
'callRecursive.'][
'tagStdWrap.']);
4139 $parts[$k] = $tag . $parts[$k] .
'</' . $tagName .
'>';
4142 } elseif ($cfg[
'HTMLtableCells']) {
4143 $rowParts = $htmlParser->splitIntoBlock(
'tr', $parts[$k]);
4144 foreach ($rowParts as $kk => $vv) {
4146 $colParts = $htmlParser->splitIntoBlock(
'td,th', $vv);
4148 foreach ($colParts as $kkk => $vvv) {
4151 $tag = $htmlParser->getFirstTag($vvv);
4152 $tagName = strtolower($htmlParser->getFirstTagName($vvv));
4153 $colParts[$kkk] = $htmlParser->removeFirstAndLastTag($vvv);
4154 if ($cfg[
'HTMLtableCells.'][$cc .
'.'][
'callRecursive'] || !isset($cfg[
'HTMLtableCells.'][$cc .
'.'][
'callRecursive']) && $cfg[
'HTMLtableCells.'][
'default.'][
'callRecursive']) {
4155 if ($cfg[
'HTMLtableCells.'][
'addChr10BetweenParagraphs']) {
4156 $colParts[$kkk] = str_replace(
'</p><p>',
'</p>' . LF .
'<p>', $colParts[$kkk]);
4158 $colParts[$kkk] = $this->
parseFunc($colParts[$kkk], $conf);
4160 $tagStdWrap = is_array($cfg[
'HTMLtableCells.'][$cc .
'.'][
'tagStdWrap.'])
4161 ? $cfg[
'HTMLtableCells.'][$cc .
'.'][
'tagStdWrap.']
4162 : $cfg[
'HTMLtableCells.'][
'default.'][
'tagStdWrap.'];
4163 if (is_array($tagStdWrap)) {
4164 $tag = $this->
stdWrap($tag, $tagStdWrap);
4166 $stdWrap = is_array($cfg[
'HTMLtableCells.'][$cc .
'.'][
'stdWrap.'])
4167 ? $cfg[
'HTMLtableCells.'][$cc .
'.'][
'stdWrap.']
4168 : $cfg[
'HTMLtableCells.'][
'default.'][
'stdWrap.'];
4169 if (is_array($stdWrap)) {
4170 $colParts[$kkk] = $this->
stdWrap($colParts[$kkk], $stdWrap);
4172 $colParts[$kkk] = $tag . $colParts[$kkk] .
'</' . $tagName .
'>';
4175 $rowParts[$kk] = implode(
'', $colParts);
4178 $parts[$k] = implode(
'', $rowParts);
4180 if (is_array($cfg[
'stdWrap.'])) {
4181 $parts[$k] = $this->
stdWrap($parts[$k], $cfg[
'stdWrap.']);
4184 $parts[$k] = $this->
_parseFunc($parts[$k], $conf);
4187 $result = implode(
'', $parts);
4188 if ($conf[
'htmlSanitize']) {
4205 if (!empty($conf[
'if.']) && !$this->
checkIf($conf[
'if.'])) {
4217 $allowTags = strtolower(str_replace(
' ',
'', $conf[
'allowTags'] ??
''));
4218 $denyTags = strtolower(str_replace(
' ',
'', $conf[
'denyTags'] ??
''));
4219 $totalLen = strlen($theValue);
4222 if (!is_array($currentTag)) {
4228 $len = strcspn(substr($theValue, $pointer + $len_p),
'<');
4230 $endChar = ord(strtolower(substr($theValue, $pointer + $len_p, 1)));
4232 }
while ($c > 0 && $endChar && ($endChar < 97 || $endChar > 122) && $endChar != 47);
4236 $tempContent = strtolower(substr($theValue, $pointer));
4237 $len = strpos($tempContent,
'</' . $currentTag[0]);
4238 if (is_string($len) && !$len) {
4239 $len = strlen($tempContent);
4244 $data = substr($theValue, $pointer, $len);
4248 $data = preg_replace(
'/^[ ]*' . CR .
'?' . LF .
'/',
'',
$data);
4251 if (!is_array($currentTag)) {
4254 $tmpConstants = $tsfe->tmpl->setup[
'constants.'] ??
null;
4255 if ($conf[
'constants'] && is_array($tmpConstants)) {
4256 foreach ($tmpConstants as $key => $val) {
4257 if (is_string($val)) {
4258 $data = str_replace(
'###' . $key .
'###', $val,
$data);
4263 if (isset($conf[
'short.']) && is_array($conf[
'short.'])) {
4264 $shortWords = $conf[
'short.'];
4265 krsort($shortWords);
4266 foreach ($shortWords as $key => $val) {
4267 if (is_string($val)) {
4273 if (isset($conf[
'plainTextStdWrap.']) && is_array($conf[
'plainTextStdWrap.'])) {
4277 if ($conf[
'userFunc'] ??
false) {
4281 if ($conf[
'makelinks'] ??
false) {
4286 if ($tsfe->no_cache && $conf[
'sword'] && is_array($tsfe->sWordList) && $tsfe->sWordRegEx) {
4289 $pregSplitMode =
'i';
4290 if (isset($tsfe->config[
'config'][
'sword_noMixedCase']) && !empty($tsfe->config[
'config'][
'sword_noMixedCase'])) {
4291 $pregSplitMode =
'';
4293 $pieces = preg_split(
'/' . $tsfe->sWordRegEx .
'/' . $pregSplitMode,
$data, 2);
4294 $newstring .= $pieces[0];
4295 $match_len = strlen(
$data) - (strlen($pieces[0]) + strlen($pieces[1]));
4297 if (strstr($pieces[0],
'<') || strstr($pieces[0],
'>')) {
4302 $inTag = strrpos($pieces[0],
'<') > strrpos($pieces[0],
'>');
4305 $match = substr(
$data, strlen($pieces[0]), $match_len);
4306 if (trim($match) && strlen($match) > 1 && !$inTag) {
4307 $match = $this->
wrap($match, $conf[
'sword']);
4310 $newstring .= $match;
4312 }
while ($pieces[1]);
4316 $contentAccum[$contentAccumP] = isset($contentAccum[$contentAccumP])
4317 ? $contentAccum[$contentAccumP] .
$data
4323 $len = strcspn(substr($theValue, $pointer),
'>') + 1;
4324 $data = substr($theValue, $pointer, $len);
4326 $tagContent = substr(
$data, 1, -2);
4328 $tagContent = substr(
$data, 1, -1);
4330 $tag = explode(
' ', trim($tagContent), 2);
4331 $tag[0] = strtolower($tag[0]);
4332 if ($tag[0][0] ===
'/') {
4333 $tag[0] = substr($tag[0], 1);
4336 if ($conf[
'tags.'][$tag[0]] ??
false) {
4340 if (!$currentTag && (!isset($tag[
'out']) || !$tag[
'out'])) {
4346 if (preg_match(
'/^(area|base|br|col|hr|img|input|meta|param)$/i', $tag[0])) {
4351 if ($currentTag[0] === $tag[0] && isset($tag[
'out']) && $tag[
'out']) {
4352 $theName = $conf[
'tags.'][$tag[0]];
4353 $theConf = $conf[
'tags.'][$tag[0] .
'.'];
4355 $stripNL = (bool)($theConf[
'stripNL'] ??
false);
4357 $breakOut = (bool)($theConf[
'breakoutTypoTagContent'] ??
false);
4358 $this->parameters = [];
4359 if ($currentTag[1]) {
4361 $params = GeneralUtility::get_tag_attributes($currentTag[1],
true);
4362 if (is_array($params)) {
4363 foreach ($params as $option => $val) {
4365 $this->parameters[strtolower($option)] = $val;
4369 $this->parameters[
'allParams'] = trim($currentTag[1]);
4373 $contentAccum[$contentAccumP - 1] = preg_replace(
'/' . CR .
'?' . LF .
'[ ]*$/',
'', $contentAccum[$contentAccumP - 1]);
4374 $contentAccum[$contentAccumP] = preg_replace(
'/^[ ]*' . CR .
'?' . LF .
'/',
'', $contentAccum[$contentAccumP]);
4375 $contentAccum[$contentAccumP] = preg_replace(
'/' . CR .
'?' . LF .
'[ ]*$/',
'', $contentAccum[$contentAccumP]);
4378 $newInput = $this->
cObjGetSingle($theName, $theConf,
'/parseFunc/.tags.' . $tag[0]);
4380 $contentAccum[$contentAccumP] = $newInput;
4384 if (!isset($contentAccum[$contentAccumP - 2])) {
4385 $contentAccum[$contentAccumP - 2] =
'';
4387 $contentAccum[$contentAccumP - 2] .= ($contentAccum[$contentAccumP - 1] ??
'') . ($contentAccum[$contentAccumP] ??
'');
4388 unset($contentAccum[$contentAccumP]);
4389 unset($contentAccum[$contentAccumP - 1]);
4390 $contentAccumP -= 2;
4397 $contentAccum[$contentAccumP] .=
$data;
4402 if (GeneralUtility::inList($allowTags, $tag[0]) || $denyTags !==
'*' && !GeneralUtility::inList($denyTags, $tag[0])) {
4403 $contentAccum[$contentAccumP] = isset($contentAccum[$contentAccumP])
4404 ? $contentAccum[$contentAccumP] .
$data
4407 $contentAccum[$contentAccumP] = isset($contentAccum[$contentAccumP])
4408 ? $contentAccum[$contentAccumP] . htmlspecialchars(
$data)
4409 : htmlspecialchars(
$data);
4415 }
while ($pointer < $totalLen);
4417 reset($contentAccum);
4418 $contentAccumCount = count($contentAccum);
4419 for ($a = 0; $a < $contentAccumCount; $a++) {
4422 if (isset($conf[
'nonTypoTagStdWrap.']) && is_array($conf[
'nonTypoTagStdWrap.'])) {
4423 $contentAccum[$a] = $this->
stdWrap($contentAccum[$a], $conf[
'nonTypoTagStdWrap.']);
4426 if (!empty($conf[
'nonTypoTagUserFunc'])) {
4427 $contentAccum[$a] = $this->
callUserFunction($conf[
'nonTypoTagUserFunc'], $conf[
'nonTypoTagUserFunc.'], $contentAccum[$a]);
4431 return implode(
'', $contentAccum);
4444 if ((
string)$theValue ===
'') {
4447 $lParts = explode(LF, $theValue);
4450 $lastPartIndex = count($lParts) - 1;
4451 if ($lParts[$lastPartIndex] ===
'' && trim($lParts[$lastPartIndex - 1], CR) ===
'') {
4455 $encapTags = GeneralUtility::trimExplode(
',', strtolower($conf[
'encapsTagList']),
true);
4456 $nonWrappedTag = $conf[
'nonWrappedTag'];
4457 $defaultAlign = isset($conf[
'defaultAlign.'])
4458 ? trim($this->
stdWrap($conf[
'defaultAlign'] ??
'', $conf[
'defaultAlign.']))
4459 : trim($conf[
'defaultAlign'] ??
'');
4462 foreach ($lParts as $k => $l) {
4467 $nonWrapped =
false;
4469 if (isset($l[0]) && $l[0] ===
'<' && substr($l, -1) ===
'>') {
4470 $fwParts = explode(
'>', substr($l, 1), 2);
4471 list($tagName) = explode(
' ', $fwParts[0], 2);
4473 if (substr($tagName, -1) ===
'/') {
4474 $tagName = substr($tagName, 0, -1);
4476 if (substr($fwParts[0], -1) ===
'/') {
4480 $attrib = GeneralUtility::get_tag_attributes(
'<' . substr($fwParts[0], 0, -1) .
'>',
true);
4483 $backParts = GeneralUtility::revExplode(
'<', substr($fwParts[1], 0, -1), 2);
4485 $attrib = GeneralUtility::get_tag_attributes(
'<' . $fwParts[0] .
'>',
true);
4486 $str_content = $backParts[0];
4487 $sameBeginEnd = substr(strtolower($backParts[1]), 1, strlen($tagName)) === strtolower($tagName);
4490 if ($sameBeginEnd && in_array(strtolower($tagName), $encapTags)) {
4491 $uTagName = strtoupper($tagName);
4492 $uTagName = strtoupper($conf[
'remapTag.'][$uTagName] ?? $uTagName);
4494 $uTagName = strtoupper($nonWrappedTag);
4497 $str_content = $lParts[$k];
4502 if (is_array($conf[
'innerStdWrap_all.'])) {
4503 $str_content = $this->
stdWrap($str_content, $conf[
'innerStdWrap_all.']);
4507 if (isset($conf[
'addAttributes.'][$uTagName .
'.']) && is_array($conf[
'addAttributes.'][$uTagName .
'.'])) {
4508 foreach ($conf[
'addAttributes.'][$uTagName .
'.'] as $kk => $vv) {
4509 if (!is_array($vv)) {
4510 if ((
string)$conf[
'addAttributes.'][$uTagName .
'.'][$kk .
'.'][
'setOnly'] ===
'blank') {
4511 if ((
string)($attrib[$kk] ??
'') ===
'') {
4514 } elseif ((
string)$conf[
'addAttributes.'][$uTagName .
'.'][$kk .
'.'][
'setOnly'] ===
'exists') {
4515 if (!isset($attrib[$kk])) {
4525 if (isset($conf[
'encapsLinesStdWrap.'][$uTagName .
'.']) && is_array($conf[
'encapsLinesStdWrap.'][$uTagName .
'.'])) {
4526 $str_content = $this->
stdWrap($str_content, $conf[
'encapsLinesStdWrap.'][$uTagName .
'.']);
4529 if ((!isset($attrib[
'align']) || !$attrib[
'align']) && $defaultAlign) {
4530 $attrib[
'align'] = $defaultAlign;
4533 $params = GeneralUtility::implodeAttributes($attrib,
true);
4534 if (!isset($conf[
'removeWrapping']) || !$conf[
'removeWrapping'] || ($emptyTag && $conf[
'removeWrapping.'][
'keepSingleTag'])) {
4535 $selfClosingTagList = [
'area',
'base',
'br',
'col',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'];
4536 if ($emptyTag && in_array(strtolower($uTagName), $selfClosingTagList,
true)) {
4537 $str_content =
'<' . strtolower($uTagName) . (trim($params) ?
' ' . trim($params) :
'') .
' />';
4539 $str_content =
'<' . strtolower($uTagName) . (trim($params) ?
' ' . trim($params) :
'') .
'>' . $str_content .
'</' . strtolower($uTagName) .
'>';
4543 if ($nonWrapped && isset($conf[
'wrapNonWrappedLines']) && $conf[
'wrapNonWrappedLines']) {
4544 $str_content = $this->
wrap($str_content, $conf[
'wrapNonWrappedLines']);
4546 $lParts[$k] = $str_content;
4548 return implode(LF, $lParts);
4565 foreach ([
'http://',
'https://'] as $scheme) {
4566 $textpieces = explode($scheme,
$data);
4567 $pieces = count($textpieces);
4568 $textstr = $textpieces[0];
4569 for ($i = 1; $i < $pieces; $i++) {
4570 $len = strcspn($textpieces[$i], chr(32) .
"\t" . CRLF);
4571 if (trim(substr($textstr, -1)) ===
'' && $len) {
4572 $lastChar = substr($textpieces[$i], $len - 1, 1);
4573 if (!preg_match(
'/[A-Za-z0-9\\/#_-]/', $lastChar)) {
4577 $parts[0] = substr($textpieces[$i], 0, $len);
4578 $parts[1] = substr($textpieces[$i], $len);
4579 $keep = $conf[
'keep'];
4580 $linkParts = parse_url($scheme . $parts[0]);
4582 if (strstr($keep,
'scheme')) {
4585 $linktxt .= $linkParts[
'host'];
4586 if (strstr($keep,
'path')) {
4587 $linktxt .= $linkParts[
'path'];
4589 if (strstr($keep,
'query') && $linkParts[
'query']) {
4590 $linktxt .=
'?' . $linkParts[
'query'];
4591 } elseif ($linkParts[
'path'] ===
'/') {
4592 $linktxt = substr($linktxt, 0, -1);
4595 if (isset($conf[
'extTarget'])) {
4596 if (isset($conf[
'extTarget.'])) {
4597 $target = $this->
stdWrap($conf[
'extTarget'], $conf[
'extTarget.']);
4599 $target = $conf[
'extTarget'];
4608 $res =
'<a href="' . htmlspecialchars($linkUrl) .
'"'
4609 . ($target !==
'' ?
' target="' . htmlspecialchars($target) .
'"' :
'')
4612 $wrap = isset($conf[
'wrap.']) ? $this->
stdWrap($conf[
'wrap'], $conf[
'wrap.']) : $conf[
'wrap'];
4613 if ((
string)$conf[
'ATagBeforeWrap'] !==
'') {
4614 $res = $res . $this->
wrap($linktxt, $wrap) .
'</a>';
4616 $res = $this->
wrap($res . $linktxt .
'</a>', $wrap);
4618 $textstr .= $res . $parts[1];
4620 $textstr .= $scheme . $textpieces[$i];
4641 $textpieces = explode(
'mailto:',
$data);
4642 $pieces = count($textpieces);
4643 $textstr = $textpieces[0];
4645 for ($i = 1; $i < $pieces; $i++) {
4646 $len = strcspn($textpieces[$i], chr(32) .
"\t" . CRLF);
4647 if (trim(substr($textstr, -1)) ===
'' && $len) {
4648 $lastChar = substr($textpieces[$i], $len - 1, 1);
4649 if (!preg_match(
'/[A-Za-z0-9]/', $lastChar)) {
4652 $parts[0] = substr($textpieces[$i], 0, $len);
4653 $parts[1] = substr($textpieces[$i], $len);
4654 $linktxt = preg_replace(
'/\\?.*/',
'', $parts[0]);
4655 list($mailToUrl, $linktxt) = $this->
getMailTo($parts[0], $linktxt);
4656 $mailToUrl = $tsfe->spamProtectEmailAddresses ===
'ascii' ? $mailToUrl : htmlspecialchars($mailToUrl);
4657 $res =
'<a href="' . $mailToUrl .
'"' . $aTagParams .
'>';
4658 $wrap = isset($conf[
'wrap.']) ? $this->
stdWrap($conf[
'wrap'], $conf[
'wrap.']) : $conf[
'wrap'];
4659 if ((
string)$conf[
'ATagBeforeWrap'] !==
'') {
4660 $res = $res . $this->
wrap($linktxt, $wrap) .
'</a>';
4662 $res = $this->
wrap($res . $linktxt .
'</a>', $wrap);
4664 $textstr .= $res . $parts[1];
4666 $textstr .=
'mailto:' . $textpieces[$i];
4698 if (empty($file) && empty($fileArray)) {
4701 if (!is_array($fileArray)) {
4702 $fileArray = (array)$fileArray;
4704 $imageResource =
null;
4705 if ($file ===
'GIFBUILDER') {
4706 $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
4708 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'gdlib']) {
4709 $gifCreator->start($fileArray, $this->data);
4710 $theImage = $gifCreator->gifBuild();
4712 $imageResource = $gifCreator->getImageDimensions($theImage);
4713 $imageResource[
'origFile'] = $theImage;
4715 if ($file instanceof File) {
4716 $fileObject = $file;
4717 } elseif ($file instanceof FileReference) {
4718 $fileObject = $file->getOriginalFile();
4721 if (isset($fileArray[
'import.']) && $fileArray[
'import.']) {
4722 $importedFile = trim($this->
stdWrap(
'', $fileArray[
'import.']));
4723 if (!empty($importedFile)) {
4724 $file = $importedFile;
4729 $treatIdAsReference = isset($fileArray[
'treatIdAsReference.']) ? $this->
stdWrap($fileArray[
'treatIdAsReference'], $fileArray[
'treatIdAsReference.']) : $fileArray[
'treatIdAsReference'];
4730 if (!empty($treatIdAsReference)) {
4736 } elseif (preg_match(
'/^(0|[1-9][0-9]*):/', $file)) {
4739 if (isset($importedFile) && !empty($importedFile) && !empty($fileArray[
'import'])) {
4740 $file = $fileArray[
'import'] . $file;
4744 }
catch (Exception $exception) {
4745 $this->logger->warning(
'The image "' . $file .
'" could not be found and won\'t be included in frontend output', [
'exception' => $exception]);
4749 if ($fileObject instanceof File) {
4750 $processingConfiguration = [];
4751 $processingConfiguration[
'width'] = isset($fileArray[
'width.']) ? $this->
stdWrap($fileArray[
'width'], $fileArray[
'width.']) : $fileArray[
'width'];
4752 $processingConfiguration[
'height'] = isset($fileArray[
'height.']) ? $this->
stdWrap($fileArray[
'height'], $fileArray[
'height.']) : $fileArray[
'height'];
4753 $processingConfiguration[
'fileExtension'] = isset($fileArray[
'ext.']) ? $this->
stdWrap($fileArray[
'ext'], $fileArray[
'ext.']) : $fileArray[
'ext'];
4754 $processingConfiguration[
'maxWidth'] = isset($fileArray[
'maxW.']) ? (int)$this->
stdWrap($fileArray[
'maxW'], $fileArray[
'maxW.']) : (int)$fileArray[
'maxW'];
4755 $processingConfiguration[
'maxHeight'] = isset($fileArray[
'maxH.']) ? (int)$this->
stdWrap($fileArray[
'maxH'], $fileArray[
'maxH.']) : (int)$fileArray[
'maxH'];
4756 $processingConfiguration[
'minWidth'] = isset($fileArray[
'minW.']) ? (int)$this->
stdWrap($fileArray[
'minW'], $fileArray[
'minW.']) : (int)$fileArray[
'minW'];
4757 $processingConfiguration[
'minHeight'] = isset($fileArray[
'minH.']) ? (int)$this->
stdWrap($fileArray[
'minH'], $fileArray[
'minH.']) : (int)$fileArray[
'minH'];
4758 $processingConfiguration[
'noScale'] = isset($fileArray[
'noScale.']) ? $this->
stdWrap($fileArray[
'noScale'], $fileArray[
'noScale.']) : $fileArray[
'noScale'];
4759 $processingConfiguration[
'additionalParameters'] = isset($fileArray[
'params.']) ? $this->
stdWrap($fileArray[
'params'], $fileArray[
'params.']) : $fileArray[
'params'];
4760 $processingConfiguration[
'frame'] = isset($fileArray[
'frame.']) ? (int)$this->
stdWrap($fileArray[
'frame'], $fileArray[
'frame.']) : (int)$fileArray[
'frame'];
4761 if ($file instanceof FileReference) {
4769 if (isset($fileArray[
'stripProfile'])) {
4770 $processingConfiguration[
'stripProfile'] = $fileArray[
'stripProfile'];
4773 if (GeneralUtility::inList(
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'imagefile_ext'], $fileObject->getExtension())) {
4774 $maskArray = $fileArray[
'm.'];
4777 if (is_array($maskArray)) {
4778 $mask = $this->
getImgResource($maskArray[
'mask'], $maskArray[
'mask.']);
4779 $bgImg = $this->
getImgResource($maskArray[
'bgImg'], $maskArray[
'bgImg.']);
4780 $bottomImg = $this->
getImgResource($maskArray[
'bottomImg'], $maskArray[
'bottomImg.']);
4781 $bottomImg_mask = $this->
getImgResource($maskArray[
'bottomImg_mask'], $maskArray[
'bottomImg_mask.']);
4783 $processingConfiguration[
'maskImages'][
'maskImage'] = $mask[
'processedFile'];
4784 $processingConfiguration[
'maskImages'][
'backgroundImage'] = $bgImg[
'processedFile'];
4785 $processingConfiguration[
'maskImages'][
'maskBottomImage'] = $bottomImg[
'processedFile'];
4786 $processingConfiguration[
'maskImages'][
'maskBottomImageMask'] = $bottomImg_mask[
'processedFile'];
4789 if ($processedFileObject->isProcessed()) {
4791 0 => (int)$processedFileObject->getProperty(
'width'),
4792 1 => (int)$processedFileObject->getProperty(
'height'),
4793 2 => $processedFileObject->getExtension(),
4794 3 => $processedFileObject->getPublicUrl(),
4795 'origFile' => $fileObject->getPublicUrl(),
4796 'origFile_mtime' => $fileObject->getModificationTime(),
4799 'originalFile' => $fileObject,
4800 'processedFile' => $processedFileObject
4808 if (!isset($imageResource)) {
4810 $theImage = GeneralUtility::makeInstance(FilePathSanitizer::class)->sanitize((
string)$file);
4811 $info = GeneralUtility::makeInstance(GifBuilder::class)->imageMagickConvert($theImage,
'WEB');
4812 $info[
'origFile'] = $theImage;
4814 $info[
'origFile_mtime'] = @filemtime($theImage);
4815 $imageResource = $info;
4816 }
catch (\
TYPO3\CMS\Core\Resource\Exception $e) {
4821 if (isset($imageResource)) {
4824 $imageResource = $hookObject->getImgResourcePostProcess($file, (array)$fileArray, $imageResource, $this);
4827 return $imageResource;
4850 if (!isset($fileArray[
'crop']) && !isset($fileArray[
'crop.'])) {
4852 $cropVariant = $fileArray[
'cropVariant'] ??
'default';
4854 return $fileCropArea->isEmpty() ? null : $fileCropArea->makeAbsoluteBasedOnFile($fileReference);
4873 $cropSettings = isset($fileArray[
'crop.'])
4874 ? $this->
stdWrap($fileArray[
'crop'], $fileArray[
'crop.'])
4875 : ($fileArray[
'crop'] ?? null);
4877 if (is_string($cropSettings)) {
4879 $cropVariant = $fileArray[
'cropVariant'] ??
'default';
4883 $cropArea = $jsonCropArea->isEmpty() ? null : $jsonCropArea->makeAbsoluteBasedOnFile($file);
4886 if ($jsonCropArea->isEmpty() && preg_match(
'/^[0-9]+,[0-9]+,[0-9]+,[0-9]+$/', $cropSettings)) {
4887 $cropSettings = explode(
',', $cropSettings);
4888 if (count($cropSettings) === 4) {
4889 $stringCropArea = GeneralUtility::makeInstance(
4893 $cropArea = $stringCropArea->isEmpty() ? null : $stringCropArea;
4927 if (!strstr($field,
'//')) {
4928 return $this->data[trim($field)] ??
null;
4930 $sections = GeneralUtility::trimExplode(
'//', $field,
true);
4931 foreach ($sections as $k) {
4932 if ((
string)$this->data[$k] !==
'') {
4933 return $this->data[$k];
4948 public function getData($string, $fieldArray =
null)
4951 if (!is_array($fieldArray)) {
4952 $fieldArray = $tsfe->page;
4955 $sections = explode(
'//', $string);
4956 foreach ($sections as $secKey => $secVal) {
4960 $parts = explode(
':', $secVal, 2);
4961 $type = strtolower(trim($parts[0]));
4962 $typesWithOutParameters = [
'level',
'date',
'current',
'pagelayout'];
4963 $key = trim($parts[1] ??
'');
4964 if (($key !=
'') || in_array($type, $typesWithOutParameters)) {
4968 $getPostArray = GeneralUtility::_GET();
4970 $retVal = $this->
getGlobal($key, $getPostArray);
4976 $retVal = getenv($key);
4982 $retVal = $this->
getGlobal($key, $fieldArray);
4988 $retVal = $this->parameters[$key];
4991 $retVal = $tsfe->register[$key] ??
null;
4997 $retVal = count($tsfe->tmpl->rootLine) - 1;
5000 $keyParts = GeneralUtility::trimExplode(
',', $key);
5001 $numericKey = $this->
getKey($keyParts[0], $tsfe->tmpl->rootLine);
5002 $retVal = $this->
rootLineValue($numericKey,
'title', strtolower($keyParts[1] ??
'') ===
'slide');
5005 $keyParts = GeneralUtility::trimExplode(
',', $key);
5006 $numericKey = $this->
getKey($keyParts[0], $tsfe->tmpl->rootLine);
5007 $retVal = $this->
rootLineValue($numericKey,
'media', strtolower($keyParts[1] ??
'') ===
'slide');
5010 $numericKey = $this->
getKey($key, $tsfe->tmpl->rootLine);
5014 $keyParts = GeneralUtility::trimExplode(
',', $key);
5015 $numericKey = $this->
getKey($keyParts[0], $tsfe->tmpl->rootLine);
5016 $retVal = $this->
rootLineValue($numericKey, $keyParts[1], strtolower($keyParts[2] ??
'') ===
'slide');
5018 case 'fullrootline':
5019 $keyParts = GeneralUtility::trimExplode(
',', $key);
5020 $fullKey = (int)$keyParts[0] - count($tsfe->tmpl->rootLine) + count($tsfe->rootLine);
5021 if ($fullKey >= 0) {
5022 $retVal = $this->
rootLineValue($fullKey, $keyParts[1], stristr($keyParts[2] ??
'',
'slide'), $tsfe->rootLine);
5029 $retVal = date($key,
$GLOBALS[
'EXEC_TIME']);
5032 $retVal = $tsfe->page[$key];
5041 $retVal = $tsfe->page[
'backend_layout'];
5044 if ($retVal ===
'-1') {
5046 } elseif ($retVal ===
'' || $retVal ===
'0') {
5050 $rootLine = $tsfe->rootLine;
5051 array_shift($rootLine);
5052 foreach ($rootLine as $rootLinePage) {
5053 $retVal = (string)$rootLinePage[
'backend_layout_next_level'];
5055 if ($retVal ===
'-1') {
5059 if ($retVal !==
'' && $retVal !==
'0') {
5065 if ($retVal ===
'0' || $retVal ===
'') {
5066 $retVal =
'default';
5073 $selectParts = GeneralUtility::trimExplode(
':', $key);
5074 $db_rec = $tsfe->sys_page->getRawRecord($selectParts[0], $selectParts[1]);
5075 if (is_array($db_rec) && $selectParts[2]) {
5076 $retVal = $db_rec[$selectParts[2]];
5080 $retVal = $tsfe->sL(
'LLL:' . $key);
5084 $retVal = GeneralUtility::makeInstance(FilePathSanitizer::class)->sanitize($key);
5085 }
catch (\
TYPO3\CMS\Core\Resource\Exception $e) {
5092 case 'parentRecordNumber':
5102 case 'fullRootLine':
5117 $keyParts = GeneralUtility::trimExplode(
':', $key,
true);
5118 if (count($keyParts) === 2 && isset($this->data[$keyParts[0]])) {
5119 $flexFormContent = $this->data[$keyParts[0]];
5120 if (!empty($flexFormContent)) {
5121 $flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
5122 $flexFormKey = str_replace(
'.',
'|', $keyParts[1]);
5123 $settings = $flexFormService->convertFlexFormContentToArray($flexFormContent);
5124 $retVal = $this->
getGlobal($flexFormKey, $settings);
5129 $keyParts = GeneralUtility::trimExplode(
'|', $key,
true);
5130 $sessionKey = array_shift($keyParts);
5132 foreach ($keyParts as $keyPart) {
5133 if (is_object($retVal)) {
5134 $retVal = $retVal->{$keyPart};
5135 } elseif (is_array($retVal)) {
5136 $retVal = $retVal[$keyPart];
5142 if (!is_scalar($retVal)) {
5147 $context = GeneralUtility::makeInstance(Context::class);
5148 list($aspectName, $propertyName) = GeneralUtility::trimExplode(
':', $key,
true, 2);
5149 $retVal = $context->getPropertyFromAspect($aspectName, $propertyName,
'');
5150 if (is_array($retVal)) {
5151 $retVal = implode(
',', $retVal);
5153 if (!is_scalar($retVal)) {
5158 $request =
$GLOBALS[
'TYPO3_REQUEST'] ??
null;
5159 $site = $request ? $request->getAttribute(
'site') :
null;
5160 if ($site instanceof Site) {
5161 if ($key ===
'identifier') {
5162 $retVal = $site->getIdentifier();
5163 } elseif ($key ===
'base') {
5164 $retVal = $site->getBase();
5168 }
catch (MissingArrayPathException $exception) {
5169 $this->logger->warning(sprintf(
'getData() with "%s" failed', $key), [
'exception' => $exception]);
5174 case 'sitelanguage':
5175 $request =
$GLOBALS[
'TYPO3_REQUEST'] ??
null;
5176 $siteLanguage = $request ? $request->getAttribute(
'language') :
null;
5177 if ($siteLanguage instanceof SiteLanguage) {
5178 $config = $siteLanguage->toArray();
5179 if (isset($config[$key])) {
5180 $retVal = $config[$key];
5187 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'getData'] ?? [] as $className) {
5188 $hookObject = GeneralUtility::makeInstance($className);
5189 if (!$hookObject instanceof ContentObjectGetDataHookInterface) {
5190 throw new \UnexpectedValueException(
'$hookObject must implement interface ' . ContentObjectGetDataHookInterface::class, 1195044480);
5192 $retVal = $hookObject->getDataExtension($string, $fieldArray, $secVal, $retVal, $this);
5207 protected function getFileDataKey($key)
5209 list($fileUidOrCurrentKeyword, $requestedFileInformationKey) = explode(
':', $key, 3);
5211 if ($fileUidOrCurrentKeyword ===
'current') {
5212 $fileObject = $this->getCurrentFile();
5215 $fileFactory = GeneralUtility::makeInstance(ResourceFactory::class);
5216 $fileObject = $fileFactory->getFileObject($fileUidOrCurrentKeyword);
5220 }
catch (Exception $exception) {
5221 $this->logger->warning(
'The file "' . $fileUidOrCurrentKeyword .
'" could not be found and won\'t be included in frontend output', [
'exception' => $exception]);
5225 if ($fileObject instanceof FileInterface) {
5227 switch ($requestedFileInformationKey) {
5229 return $fileObject->getName();
5231 if (method_exists($fileObject,
'getUid')) {
5232 return $fileObject->getUid();
5236 if ($fileObject instanceof FileReference) {
5237 return $fileObject->getOriginalFile()->getUid();
5241 return $fileObject->getSize();
5243 return $fileObject->getSha1();
5245 return $fileObject->getExtension();
5247 return $fileObject->getMimeType();
5249 return $fileObject->getContents();
5251 return $fileObject->getPublicUrl();
5254 return $fileObject->getProperty($requestedFileInformationKey);
5258 return 'Error: no file object';
5273 public function rootLineValue($key, $field, $slideBack =
false, $altRootLine =
'')
5275 $rootLine = is_array($altRootLine) ? $altRootLine : $this->getTypoScriptFrontendController()->tmpl->rootLine;
5277 return $rootLine[$key][$field];
5279 for ($a = $key; $a >= 0; $a--) {
5280 $val = $rootLine[$a][$field];
5298 public function getGlobal($keyString, $source =
null)
5300 $keys = explode(
'|', $keyString);
5301 $numberOfLevels = count($keys);
5302 $rootKey = trim($keys[0]);
5303 $value = isset($source) ? $source[$rootKey] :
$GLOBALS[$rootKey];
5304 for ($i = 1; $i < $numberOfLevels && isset($value); $i++) {
5305 $currentKey = trim($keys[$i]);
5306 if (is_object($value)) {
5307 $value = $value->{$currentKey};
5308 } elseif (is_array($value)) {
5309 $value = $value[$currentKey];
5315 if (!is_scalar($value)) {
5331 public function getKey($key, $arr)
5334 if (is_array($arr)) {
5336 $key = count($arr) + $key;
5365 protected function resolveMixedLinkParameter($linkText, $mixedLinkParameter, &$configuration = [])
5367 $linkParameter =
null;
5370 $linkParameterParts = GeneralUtility::makeInstance(TypoLinkCodecService::class)->decode($mixedLinkParameter);
5373 $linkHandlerExploded = explode(
':', $linkParameterParts[
'url'], 2);
5374 $linkHandlerKeyword = $linkHandlerExploded[0] ??
null;
5375 $linkHandlerValue = $linkHandlerExploded[1] ??
null;
5376 if (!empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'typolinkLinkHandler'][$linkHandlerKeyword])
5377 && (
string)$linkHandlerValue !==
''
5379 $linkHandlerObj = GeneralUtility::makeInstance(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'typolinkLinkHandler'][$linkHandlerKeyword]);
5380 if (method_exists($linkHandlerObj,
'main')) {
5381 return $linkHandlerObj->main($linkText, $configuration, $linkHandlerKeyword, $linkHandlerValue, $mixedLinkParameter, $this);
5385 if (in_array(strtolower(preg_replace(
'#\s|[[:cntrl:]]#',
'', $linkHandlerKeyword)), [
'javascript',
'data'],
true)) {
5389 $linkParameter = $linkParameterParts[
'url'];
5392 if ($linkParameterParts[
'additionalParams'] !==
'') {
5393 $forceParams = $linkParameterParts[
'additionalParams'];
5395 $configuration[
'additionalParams'] .= $forceParams[0] ===
'&' ? $forceParams :
'&' . $forceParams;
5399 'href' => $linkParameter,
5400 'target' => $linkParameterParts[
'target'],
5401 'class' => $linkParameterParts[
'class'],
5402 'title' => $linkParameterParts[
'title']
5420 public function typoLink($linkText, $conf)
5422 $linkText = (string)$linkText;
5423 $tsfe = $this->getTypoScriptFrontendController();
5425 $linkParameter = trim(
5426 (isset($conf[
'parameter.']) ??
'')
5427 ? $this->stdWrap($conf[
'parameter'] ??
'', $conf[
'parameter.'])
5428 : ($conf[
'parameter'] ??
'')
5430 $this->lastTypoLinkUrl =
'';
5431 $this->lastTypoLinkTarget =
'';
5433 $resolvedLinkParameters = $this->resolveMixedLinkParameter($linkText, $linkParameter, $conf);
5435 if (!is_array($resolvedLinkParameters)) {
5436 return $resolvedLinkParameters;
5438 $linkParameter = $resolvedLinkParameters[
'href'];
5439 $target = $resolvedLinkParameters[
'target'];
5440 $title = $resolvedLinkParameters[
'title'];
5442 if (!$linkParameter) {
5443 return $this->resolveAnchorLink($linkText, $conf ?? []);
5447 $linkService = GeneralUtility::makeInstance(LinkService::class);
5449 $linkDetails = $linkService->resolve($linkParameter);
5450 }
catch (Exception\InvalidPathException $exception) {
5451 $this->logger->warning(
'The link could not be generated', [
'exception' => $exception]);
5455 $linkDetails[
'typoLinkParameter'] = $linkParameter;
5456 if (isset($linkDetails[
'type']) && isset(
$GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'typolinkBuilder'][$linkDetails[
'type']])) {
5458 $linkBuilder = GeneralUtility::makeInstance(
5459 $GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'typolinkBuilder'][$linkDetails[
'type']],
5464 list($this->lastTypoLinkUrl, $linkText, $target) = $linkBuilder->build($linkDetails, $linkText, $target, $conf);
5465 $this->lastTypoLinkTarget = htmlspecialchars($target);
5466 $this->lastTypoLinkLD[
'target'] = htmlspecialchars($target);
5467 $this->lastTypoLinkLD[
'totalUrl'] = $this->lastTypoLinkUrl;
5468 }
catch (UnableToLinkException $e) {
5469 $this->logger->debug(sprintf(
'Unable to link "%s": %s', $e->getLinkText(), $e->getMessage()), [
'exception' => $e]);
5472 return $e->getLinkText();
5474 } elseif (isset($linkDetails[
'url'])) {
5475 $this->lastTypoLinkUrl = $linkDetails[
'url'];
5476 $this->lastTypoLinkTarget = htmlspecialchars($target);
5477 $this->lastTypoLinkLD[
'target'] = htmlspecialchars($target);
5478 $this->lastTypoLinkLD[
'totalUrl'] = $this->lastTypoLinkUrl;
5484 $url = $this->lastTypoLinkUrl;
5486 'aTagParams' => $this->getATagParams($conf) . $this->extLinkATagParams($this->lastTypoLinkUrl, $linkDetails[
'type']),
5488 'TYPE' => $linkDetails[
'type']
5492 if (!empty($finalTagParts[
'aTagParams'])) {
5493 $aTagParams = GeneralUtility::get_tag_attributes($finalTagParts[
'aTagParams'],
true);
5494 if (isset($aTagParams[
'href'])) {
5495 unset($aTagParams[
'href']);
5496 $finalTagParts[
'aTagParams'] = GeneralUtility::implodeAttributes($aTagParams,
true);
5501 $tagAttributes = [];
5504 if (empty($title)) {
5505 $title = $conf[
'title'] ??
'';
5506 if (isset($conf[
'title.']) && is_array($conf[
'title.'])) {
5507 $title = $this->stdWrap($title, $conf[
'title.']);
5512 $JSwindowParts = [];
5513 $JSwindowParams =
'';
5514 if ($target && preg_match(
'/^([0-9]+)x([0-9]+)(:(.*)|.*)$/', $target, $JSwindowParts)) {
5516 $JSwindow_tempParamsArr = GeneralUtility::trimExplode(
',', strtolower($conf[
'JSwindow_params'] .
',' . $JSwindowParts[4]),
true);
5517 $JSwindow_paramsArr = [];
5518 foreach ($JSwindow_tempParamsArr as $JSv) {
5519 list($JSp, $JSv) = explode(
'=', $JSv, 2);
5520 $JSwindow_paramsArr[$JSp] = $JSp .
'=' . $JSv;
5523 $JSwindow_paramsArr[
'width'] =
'width=' . $JSwindowParts[1];
5524 $JSwindow_paramsArr[
'height'] =
'height=' . $JSwindowParts[2];
5526 $JSwindowParams = implode(
',', $JSwindow_paramsArr);
5529 if (!$JSwindowParams && $linkDetails[
'type'] === LinkService::TYPE_EMAIL && $tsfe->spamProtectEmailAddresses ===
'ascii') {
5530 $tagAttributes[
'href'] = $finalTagParts[
'url'];
5532 $tagAttributes[
'href'] = htmlspecialchars($finalTagParts[
'url']);
5534 if (!empty($title)) {
5535 $tagAttributes[
'title'] = htmlspecialchars($title);
5539 if (!empty($target)) {
5540 $tagAttributes[
'target'] = htmlspecialchars($target);
5541 } elseif ($JSwindowParams && !in_array($tsfe->xhtmlDoctype, [
'xhtml_strict',
'xhtml_11'],
true)) {
5543 $tagAttributes[
'target'] =
'FEopenLink';
5546 if ($JSwindowParams) {
5547 $onClick =
'openPic(' . GeneralUtility::quoteJSvalue($tsfe->baseUrlWrap($finalTagParts[
'url'])) .
',\'FEopenLink\',' . GeneralUtility::quoteJSvalue($JSwindowParams) .
');return false;';
5548 $tagAttributes[
'onclick'] = htmlspecialchars($onClick);
5549 $this->getTypoScriptFrontendController()->setJS(
'openPic');
5552 if (!empty($resolvedLinkParameters[
'class'])) {
5553 $tagAttributes[
'class'] = htmlspecialchars($resolvedLinkParameters[
'class']);
5558 $finalTagAttributes = array_merge($tagAttributes, GeneralUtility::get_tag_attributes($finalTagParts[
'aTagParams']));
5559 $finalAnchorTag =
'<a ' . GeneralUtility::implodeAttributes($finalTagAttributes) .
'>';
5562 $finalTagParts[
'targetParams'] = !empty($tagAttributes[
'target']) ?
' target="' . $tagAttributes[
'target'] .
'"' :
'';
5563 $this->lastTypoLinkTarget = $target;
5566 if ($conf[
'userFunc'] ??
false) {
5567 $finalTagParts[
'TAG'] = $finalAnchorTag;
5568 $finalAnchorTag = $this->callUserFunction($conf[
'userFunc'], $conf[
'userFunc.'], $finalTagParts);
5574 'linktxt' => &$linkText,
5575 'finalTag' => &$finalAnchorTag,
5576 'finalTagParts' => &$finalTagParts,
5577 'linkDetails' => &$linkDetails,
5578 'tagAttributes' => &$finalTagAttributes
5580 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'tslib/class.tslib_content.php'][
'typoLink_PostProc'] ?? [] as $_funcRef) {
5581 GeneralUtility::callUserFunction($_funcRef, $_params, $this);
5585 if ($conf[
'returnLast'] ??
false) {
5586 switch ($conf[
'returnLast']) {
5588 return $this->lastTypoLinkUrl;
5590 return $this->lastTypoLinkTarget;
5594 $wrap = isset($conf[
'wrap.'])
5595 ? $this->stdWrap($conf[
'wrap'] ??
'', $conf[
'wrap.'])
5596 : $conf[
'wrap'] ??
'';
5598 if ($conf[
'ATagBeforeWrap'] ??
false) {
5599 return $finalAnchorTag . $this->wrap($linkText, $wrap) .
'</a>';
5601 return $this->wrap($finalAnchorTag . $linkText .
'</a>', $wrap);
5611 public function typoLink_URL($conf)
5613 $this->typoLink(
'|', $conf);
5614 return $this->lastTypoLinkUrl;
5630 public function getTypoLink($label, $params, $urlParameters = [], $target =
'')
5633 $conf[
'parameter'] = $params;
5635 $conf[
'target'] = $target;
5636 $conf[
'extTarget'] = $target;
5637 $conf[
'fileTarget'] = $target;
5639 if (is_array($urlParameters)) {
5640 if (!empty($urlParameters)) {
5641 $conf[
'additionalParams'] .= HttpUtility::buildQueryString($urlParameters,
'&');
5644 $conf[
'additionalParams'] .= $urlParameters;
5646 $out = $this->typoLink($label, $conf);
5657 public function getUrlToCurrentLocation($addQueryString =
true)
5660 $conf[
'parameter'] = $this->getTypoScriptFrontendController()->id .
',' . $this->getTypoScriptFrontendController()->type;
5661 if ($addQueryString) {
5662 $conf[
'addQueryString'] =
'1';
5663 $linkVars = implode(
',', array_keys(GeneralUtility::explodeUrl2Array($this->getTypoScriptFrontendController()->linkVars)));
5664 $conf[
'addQueryString.'] = [
5666 'exclude' =>
'id,type,cHash' . ($linkVars ?
',' . $linkVars :
'')
5668 $conf[
'useCacheHash'] = GeneralUtility::_GET(
'cHash') ?
'1' :
'0';
5671 return $this->typoLink_URL($conf);
5683 public function getTypoLink_URL($params, $urlParameters = [], $target =
'')
5685 $this->getTypoLink(
'', $params, $urlParameters, $target);
5686 return $this->lastTypoLinkUrl;
5697 public function typolinkWrap($conf)
5699 trigger_error(
'ContentObjectRenderer->typolinkWrap() will be removed in TYPO3 v10.0. Use $cObj->typoLink() instead.', E_USER_DEPRECATED);
5700 $k = md5(microtime());
5701 return explode($k, $this->typoLink($k, $conf));
5713 public function currentPageUrl($urlParameters = [], $id = 0)
5715 trigger_error(
'ContentObjectRenderer->currentPageUrl() will be removed in TYPO3 v10.0. Use $cObj->getTypoLink_URL() instead.', E_USER_DEPRECATED);
5716 $tsfe = $this->getTypoScriptFrontendController();
5717 return $this->getTypoLink_URL($id ?: $tsfe->id, $urlParameters, $tsfe->sPre);
5729 protected function processUrl($context, $url, $typolinkConfiguration = [])
5731 $urlProcessors =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'urlProcessing'][
'urlProcessors'] ?? [];
5732 if (empty($urlProcessors)) {
5736 foreach ($urlProcessors as $identifier => $configuration) {
5737 if (empty($configuration) || !is_array($configuration)) {
5738 throw new \RuntimeException(
'Missing configuration for URI processor "' . $identifier .
'".', 1442050529);
5740 if (!is_string($configuration[
'processor']) || empty($configuration[
'processor']) || !class_exists($configuration[
'processor']) || !is_subclass_of($configuration[
'processor'], UrlProcessorInterface::class)) {
5741 throw new \RuntimeException(
'The URI processor "' . $identifier .
'" defines an invalid provider. Ensure the class exists and implements the "' . UrlProcessorInterface::class .
'".', 1442050579);
5745 $orderedProcessors = GeneralUtility::makeInstance(DependencyOrderingService::class)->orderByDependencies($urlProcessors);
5746 $keepProcessing =
true;
5748 foreach ($orderedProcessors as $configuration) {
5750 $urlProcessor = GeneralUtility::makeInstance($configuration[
'processor']);
5751 $url = $urlProcessor->process($context, $url, $typolinkConfiguration, $this, $keepProcessing);
5752 if (!$keepProcessing) {
5769 public function getMailTo($mailAddress, $linktxt)
5771 $mailAddress = (string)$mailAddress;
5772 if ((
string)$linktxt ===
'') {
5773 $linktxt = htmlspecialchars($mailAddress);
5776 $originalMailToUrl =
'mailto:' . $mailAddress;
5777 $mailToUrl = $this->processUrl(UrlProcessorInterface::CONTEXT_MAIL, $originalMailToUrl);
5780 if ($mailToUrl === $originalMailToUrl) {
5781 $tsfe = $this->getTypoScriptFrontendController();
5782 if ($tsfe->spamProtectEmailAddresses) {
5783 $mailToUrl = $this->encryptEmail($mailToUrl, $tsfe->spamProtectEmailAddresses);
5784 if ($tsfe->spamProtectEmailAddresses !==
'ascii') {
5785 $encodedForJsAndHref = rawurlencode(GeneralUtility::quoteJSvalue($mailToUrl));
5786 $mailToUrl =
'javascript:linkTo_UnCryptMailto(' . $encodedForJsAndHref .
');';
5788 $atLabel = trim($tsfe->config[
'config'][
'spamProtectEmailAddresses_atSubst']) ?:
'(at)';
5789 $spamProtectedMailAddress = str_replace(
'@', $atLabel, htmlspecialchars($mailAddress));
5790 if ($tsfe->config[
'config'][
'spamProtectEmailAddresses_lastDotSubst']) {
5791 $lastDotLabel = trim($tsfe->config[
'config'][
'spamProtectEmailAddresses_lastDotSubst']);
5792 $lastDotLabel = $lastDotLabel ? $lastDotLabel :
'(dot)';
5793 $spamProtectedMailAddress = preg_replace(
'/\\.([^\\.]+)$/', $lastDotLabel .
'$1', $spamProtectedMailAddress);
5795 $linktxt = str_ireplace($mailAddress, $spamProtectedMailAddress, $linktxt);
5799 return [$mailToUrl, $linktxt];
5809 protected function encryptEmail(
string $string, $type): string
5813 if ($type ===
'ascii') {
5814 foreach (preg_split(
'//u', $string, -1, PREG_SPLIT_NO_EMPTY) as $char) {
5815 $out .=
'&#' . mb_ord($char) .
';';
5819 $len = strlen($string);
5820 $offset = (int)$type;
5821 for ($i = 0; $i < $len; $i++) {
5822 $charValue = ord($string[$i]);
5824 if ($charValue >= 43 && $charValue <= 58) {
5825 $out .= $this->encryptCharcode($charValue, 43, 58, $offset);
5826 } elseif ($charValue >= 64 && $charValue <= 90) {
5828 $out .= $this->encryptCharcode($charValue, 64, 90, $offset);
5829 } elseif ($charValue >= 97 && $charValue <= 122) {
5831 $out .= $this->encryptCharcode($charValue, 97, 122, $offset);
5833 $out .= $string[$i];
5847 protected function decryptEmail(
string $string, $type): string
5851 if ($type ===
'ascii') {
5852 foreach (preg_split(
'//u', $string, -1, PREG_SPLIT_NO_EMPTY) as $char) {
5853 $out .=
'&#' . mb_ord($char) .
';';
5857 $len = strlen($string);
5858 $offset = (int)$type * -1;
5859 for ($i = 0; $i < $len; $i++) {
5860 $charValue = ord($string[$i]);
5862 if ($charValue >= 43 && $charValue <= 58) {
5863 $out .= $this->encryptCharcode($charValue, 43, 58, $offset);
5864 } elseif ($charValue >= 64 && $charValue <= 90) {
5866 $out .= $this->encryptCharcode($charValue, 64, 90, $offset);
5867 } elseif ($charValue >= 97 && $charValue <= 122) {
5869 $out .= $this->encryptCharcode($charValue, 97, 122, $offset);
5871 $out .= $string[$i];
5888 protected function encryptCharcode($n, $start, $end, $offset)
5891 if ($offset > 0 && $n > $end) {
5892 $n = $start + ($n - $end - 1);
5893 } elseif ($offset < 0 && $n < $start) {
5894 $n = $end - ($start - $n - 1);
5908 public function getQueryArguments($conf, $overruleQueryArguments = [], $forceOverruleArguments =
false)
5910 $method = (string)($conf[
'method'] ??
'');
5913 $currentQueryArray = GeneralUtility::_GET();
5916 $currentQueryArray = GeneralUtility::_POST();
5919 $currentQueryArray = GeneralUtility::_GET();
5920 ArrayUtility::mergeRecursiveWithOverrule($currentQueryArray, GeneralUtility::_POST());
5923 $currentQueryArray = GeneralUtility::_POST();
5924 ArrayUtility::mergeRecursiveWithOverrule($currentQueryArray, GeneralUtility::_GET());
5927 $currentQueryArray = [];
5928 parse_str($this->getEnvironmentVariable(
'QUERY_STRING'), $currentQueryArray);
5930 if ($conf[
'exclude'] ??
false) {
5931 $excludeString = str_replace(
',',
'&', $conf[
'exclude']);
5932 $excludedQueryParts = [];
5933 parse_str($excludeString, $excludedQueryParts);
5936 $newQueryArray = ArrayUtility::arrayDiffAssocRecursive($currentQueryArray, $excludedQueryParts);
5938 $newQueryArray = $currentQueryArray;
5940 ArrayUtility::mergeRecursiveWithOverrule($newQueryArray, $overruleQueryArguments, $forceOverruleArguments);
5941 return HttpUtility::buildQueryString($newQueryArray,
'&');
5960 public function wrap($content, $wrap, $char =
'|')
5963 $wrapArr = explode($char, $wrap);
5964 $content = trim($wrapArr[0] ??
'') . $content . trim($wrapArr[1] ??
'');
5979 public function noTrimWrap($content, $wrap, $char =
'|')
5984 $wrapArr = explode($char, $wrap, 4);
5985 $content = $wrapArr[1] . $content . $wrapArr[2];
6000 public function callUserFunction($funcName, $conf, $content)
6003 $parts = explode(
'->', $funcName);
6004 if (count($parts) === 2) {
6006 if (class_exists($parts[0])) {
6007 $classObj = GeneralUtility::makeInstance($parts[0]);
6008 if (is_object($classObj) && method_exists($classObj, $parts[1])) {
6009 $classObj->cObj = $this;
6010 $content = call_user_func_array([
6018 $this->getTimeTracker()->setTSlogMessage(
'Method "' . $parts[1] .
'" did not exist in class "' . $parts[0] .
'"', 3);
6021 $this->getTimeTracker()->setTSlogMessage(
'Class "' . $parts[0] .
'" did not exist', 3);
6023 } elseif (function_exists($funcName)) {
6024 $content = call_user_func($funcName, $content, $conf);
6026 $this->getTimeTracker()->setTSlogMessage(
'Function "' . $funcName .
'" did not exist', 3);
6037 public function keywords($content)
6039 $listArr = preg_split(
'/[,;' . LF .
']/', $content);
6040 foreach ($listArr as $k => $v) {
6041 $listArr[$k] = trim($v);
6043 return implode(
',', $listArr);
6054 public function caseshift($theValue, $case)
6056 switch (strtolower($case)) {
6058 $theValue = mb_strtoupper($theValue,
'utf-8');
6061 $theValue = mb_strtolower($theValue,
'utf-8');
6064 $theValue = mb_convert_case($theValue, MB_CASE_TITLE,
'utf-8');
6067 $firstChar = mb_substr($theValue, 0, 1,
'utf-8');
6068 $firstChar = mb_strtoupper($firstChar,
'utf-8');
6069 $remainder = mb_substr($theValue, 1,
null,
'utf-8');
6070 $theValue = $firstChar . $remainder;
6073 $firstChar = mb_substr($theValue, 0, 1,
'utf-8');
6074 $firstChar = mb_strtolower($firstChar,
'utf-8');
6075 $remainder = mb_substr($theValue, 1,
null,
'utf-8');
6076 $theValue = $firstChar . $remainder;
6078 case 'uppercamelcase':
6079 $theValue = GeneralUtility::underscoredToUpperCamelCase($theValue);
6081 case 'lowercamelcase':
6082 $theValue = GeneralUtility::underscoredToLowerCamelCase($theValue);
6096 public function HTMLcaseshift($theValue, $case)
6101 $totalLen = strlen($theValue);
6104 $len = strcspn(substr($theValue, $pointer),
'<');
6105 $newVal .= $this->caseshift(substr($theValue, $pointer, $len), $case);
6108 $len = strcspn(substr($theValue, $pointer),
'>') + 1;
6109 $newVal .= substr($theValue, $pointer, $len);
6113 }
while ($pointer < $totalLen);
6124 public function calcAge($seconds, $labels)
6126 if (MathUtility::canBeInterpretedAsInteger($labels)) {
6127 $labels =
' min| hrs| days| yrs| min| hour| day| year';
6129 $labels = str_replace(
'"',
'', $labels);
6131 $labelArr = explode(
'|', $labels);
6132 if (count($labelArr) === 4) {
6133 $labelArr = array_merge($labelArr, $labelArr);
6135 $absSeconds = abs($seconds);
6136 $sign = $seconds > 0 ? 1 : -1;
6137 if ($absSeconds < 3600) {
6138 $val = round($absSeconds / 60);
6139 $seconds = $sign * $val . ($val == 1 ? $labelArr[4] : $labelArr[0]);
6140 } elseif ($absSeconds < 24 * 3600) {
6141 $val = round($absSeconds / 3600);
6142 $seconds = $sign * $val . ($val == 1 ? $labelArr[5] : $labelArr[1]);
6143 } elseif ($absSeconds < 365 * 24 * 3600) {
6144 $val = round($absSeconds / (24 * 3600));
6145 $seconds = $sign * $val . ($val == 1 ? $labelArr[6] : $labelArr[2]);
6147 $val = round($absSeconds / (365 * 24 * 3600));
6148 $seconds = $sign * $val . ($val == 1 ? ($labelArr[7] ??
null) : ($labelArr[3] ??
null));
6164 public function sendNotifyEmail($message, $recipients, $cc, $senderAddress, $senderName =
'', $replyTo =
'')
6167 $mail = GeneralUtility::makeInstance(MailMessage::class);
6168 $senderName = trim($senderName);
6169 $senderAddress = trim($senderAddress);
6170 if ($senderName !==
'' && $senderAddress !==
'') {
6171 $mail->setFrom([$senderAddress => $senderName]);
6172 } elseif ($senderAddress !==
'') {
6173 $mail->setFrom([$senderAddress]);
6175 $parsedReplyTo = MailUtility::parseAddresses($replyTo);
6176 if (!empty($parsedReplyTo)) {
6177 $mail->setReplyTo($parsedReplyTo);
6179 $message = trim($message);
6180 if ($message !==
'') {
6182 $messageParts = explode(LF, $message, 2);
6183 $subject = trim($messageParts[0]);
6184 $plainMessage = trim($messageParts[1]);
6185 $parsedRecipients = MailUtility::parseAddresses($recipients);
6186 if (!empty($parsedRecipients)) {
6187 $mail->setTo($parsedRecipients)
6188 ->setSubject($subject)
6189 ->setBody($plainMessage);
6192 $parsedCc = MailUtility::parseAddresses($cc);
6193 if (!empty($parsedCc)) {
6194 $from = $mail->getFrom();
6196 $mail = GeneralUtility::makeInstance(MailMessage::class);
6197 if (!empty($parsedReplyTo)) {
6198 $mail->setReplyTo($parsedReplyTo);
6200 $mail->setFrom($from)
6202 ->setSubject($subject)
6203 ->setBody($plainMessage);
6219 public function mergeTSRef($confArr, $prop)
6221 if ($confArr[$prop][0] ===
'<') {
6222 $key = trim(substr($confArr[$prop], 1));
6223 $cF = GeneralUtility::makeInstance(TypoScriptParser::class);
6225 $old_conf = $confArr[$prop .
'.'];
6226 list(, $conf) = $cF->getVal($key, $this->getTypoScriptFrontendController()->tmpl->setup);
6227 if (is_array($old_conf) && !empty($old_conf)) {
6228 $conf = is_array($conf) ? array_replace_recursive($conf, $old_conf) : $old_conf;
6230 $confArr[$prop .
'.'] = $conf;
6257 public function enableFields($table, $show_hidden =
false, array $ignore_array = [])
6259 trigger_error(
'cObj->enableFields() will be removed in TYPO3 v10.0. should be used from the PageRepository->enableFields() functionality directly.', E_USER_DEPRECATED);
6260 return $this->getTypoScriptFrontendController()->sys_page->enableFields($table, $show_hidden ?
true : -1, $ignore_array);
6289 public function getTreeList($id, $depth, $begin = 0, $dontCheckEnableFields =
false, $addSelectFields =
'', $moreWhereClauses =
'', array $prevId_array = [], $recursionLevel = 0)
6297 $allFields =
'uid,hidden,starttime,endtime,fe_group,extendToSubpages,doktype,php_tree_stop,mount_pid,mount_pid_ol,t3ver_state' . $addSelectFields;
6298 $depth = (int)$depth;
6299 $begin = (int)$begin;
6305 $tsfe = $this->getTypoScriptFrontendController();
6306 if (!$recursionLevel) {
6313 $dontCheckEnableFields,
6317 GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect(
'frontend.user',
'groupIds', [0, -1])
6319 $requestHash = md5(serialize($parameters));
6320 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
6321 ->getQueryBuilderForTable(
'cache_treelist');
6322 $cacheEntry = $queryBuilder->select(
'treelist')
6323 ->from(
'cache_treelist')
6325 $queryBuilder->expr()->eq(
6327 $queryBuilder->createNamedParameter($requestHash, \PDO::PARAM_STR)
6329 $queryBuilder->expr()->orX(
6330 $queryBuilder->expr()->gt(
6332 $queryBuilder->createNamedParameter(
$GLOBALS[
'EXEC_TIME'], \PDO::PARAM_INT)
6334 $queryBuilder->expr()->eq(
'expires', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT))
6341 if (is_array($cacheEntry)) {
6343 return $cacheEntry[
'treelist'];
6347 $addId = $id = abs($id);
6350 if ($tsfe->sys_page->getRawRecord(
'pages', $id,
'uid')) {
6352 $mount_info = $tsfe->sys_page->getMountPointInfo($id);
6353 if (is_array($mount_info)) {
6354 $id = $mount_info[
'mount_pid'];
6356 if ($addId && $mount_info[
'overlay']) {
6367 $prevId_array[] = $id;
6371 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
6372 $queryBuilder->getRestrictions()
6374 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
6375 $queryBuilder->select(...GeneralUtility::trimExplode(
',', $allFields,
true))
6378 $queryBuilder->expr()->eq(
6380 $queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
6383 $queryBuilder->expr()->eq(
'sys_language_uid', 0)
6385 ->orderBy(
'sorting');
6387 if (!empty($moreWhereClauses)) {
6388 $queryBuilder->andWhere(QueryHelper::stripLogicalOperatorPrefix($moreWhereClauses));
6391 $result = $queryBuilder->execute();
6392 while ($row = $result->fetch()) {
6394 $versionState = VersionState::cast($row[
't3ver_state']);
6395 $tsfe->sys_page->versionOL(
'pages', $row);
6396 if ((
int)$row[
'doktype'] === PageRepository::DOKTYPE_RECYCLER
6397 || (
int)$row[
'doktype'] === PageRepository::DOKTYPE_BE_USER_SECTION
6398 || $versionState->indicatesPlaceholder()
6407 $next_id = $row[
'uid'];
6408 $mount_info = $tsfe->sys_page->getMountPointInfo($next_id, $row);
6410 if (is_array($mount_info) && $mount_info[
'overlay']) {
6411 $next_id = $mount_info[
'mount_pid'];
6412 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
6413 ->getQueryBuilderForTable(
'pages');
6414 $queryBuilder->getRestrictions()
6416 ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
6417 $queryBuilder->select(...GeneralUtility::trimExplode(
',', $allFields,
true))
6420 $queryBuilder->expr()->eq(
6422 $queryBuilder->createNamedParameter($next_id, \PDO::PARAM_INT)
6425 ->orderBy(
'sorting')
6428 if (!empty($moreWhereClauses)) {
6429 $queryBuilder->andWhere(QueryHelper::stripLogicalOperatorPrefix($moreWhereClauses));
6432 $row = $queryBuilder->execute()->fetch();
6433 $tsfe->sys_page->versionOL(
'pages', $row);
6434 if ((
int)$row[
'doktype'] === PageRepository::DOKTYPE_RECYCLER
6435 || (
int)$row[
'doktype'] === PageRepository::DOKTYPE_BE_USER_SECTION
6436 || $versionState->indicatesPlaceholder()
6445 if ($dontCheckEnableFields || $tsfe->checkPagerecordForIncludeSection($row)) {
6448 if ($dontCheckEnableFields || $tsfe->checkEnableFields($row)) {
6449 $theList[] = $next_id;
6453 if ($depth > 1 && !$row[
'php_tree_stop']) {
6455 if (is_array($mount_info) && !$mount_info[
'overlay']) {
6456 $next_id = $mount_info[
'mount_pid'];
6459 if (!in_array($next_id, $prevId_array)) {
6460 $theList = array_merge(
6461 GeneralUtility::intExplode(
6467 $dontCheckEnableFields,
6483 if (!$recursionLevel) {
6488 $theList[] = $addId;
6493 'md5hash' => $requestHash,
6495 'treelist' => implode(
',', $theList),
6501 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable(
'cache_treelist');
6503 $connection->transactional(
function ($connection) use ($cacheEntry) {
6504 $connection->insert(
'cache_treelist', $cacheEntry);
6506 }
catch (\Throwable $e) {
6511 return implode(
',', $theList);
6523 public function searchWhere($searchWords, $searchFieldList, $searchTable)
6525 if (!$searchWords) {
6529 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
6530 ->getQueryBuilderForTable($searchTable);
6532 $prefixTableName = $searchTable ? $searchTable .
'.' :
'';
6534 $where = $queryBuilder->expr()->andX();
6535 $searchFields = explode(
',', $searchFieldList);
6536 $searchWords = preg_split(
'/[ ,]/', $searchWords);
6537 foreach ($searchWords as $searchWord) {
6538 $searchWord = trim($searchWord);
6539 if (strlen($searchWord) < 3) {
6542 $searchWordConstraint = $queryBuilder->expr()->orX();
6543 $searchWord = $queryBuilder->escapeLikeWildcards($searchWord);
6544 foreach ($searchFields as $field) {
6545 $searchWordConstraint->add(
6546 $queryBuilder->expr()->like($prefixTableName . $field, $queryBuilder->quote(
'%' . $searchWord .
'%'))
6550 if ($searchWordConstraint->count()) {
6551 $where->add($searchWordConstraint);
6555 if ((
string)$where ===
'') {
6559 return ' AND (' . (string)$where .
')';
6571 public function exec_getQuery($table, $conf)
6573 $statement = $this->getQuery($table, $conf);
6574 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
6576 return $connection->executeQuery($statement);
6588 public function getRecords($tableName, array $queryConfiguration)
6592 $statement = $this->exec_getQuery($tableName, $queryConfiguration);
6594 $tsfe = $this->getTypoScriptFrontendController();
6595 while ($row = $statement->fetch()) {
6597 $tsfe->sys_page->versionOL($tableName, $row,
true);
6600 if (is_array($row)) {
6601 $row = $tsfe->sys_page->getLanguageOverlay($tableName, $row);
6605 if (is_array($row)) {
6626 public function getQuery($table, $conf, $returnQueryArray =
false)
6629 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
6645 foreach ($properties as $property) {
6646 $conf[$property] = trim(
6647 isset($conf[$property .
'.'])
6648 ? $this->stdWrap($conf[$property], $conf[$property .
'.'])
6651 if ($conf[$property] ===
'') {
6652 unset($conf[$property]);
6653 } elseif (in_array($property, [
'languageField',
'selectFields',
'join',
'leftjoin',
'rightjoin',
'where'],
true)) {
6654 $conf[$property] = QueryHelper::quoteDatabaseIdentifiers($connection, $conf[$property]);
6656 if (isset($conf[$property .
'.'])) {
6658 unset($conf[$property .
'.']);
6662 $queryMarkers = $this->getQueryMarkers($table, $conf);
6664 foreach ($queryMarkers as $marker => $markerValue) {
6677 foreach ($properties as $property) {
6678 if ($conf[$property]) {
6679 $conf[$property] = str_replace(
'###' . $marker .
'###', $markerValue, $conf[$property]);
6686 if (isset($conf[
'recursive'])) {
6687 $conf[
'recursive'] = (int)$conf[
'recursive'];
6688 if ($conf[
'recursive'] > 0) {
6689 $pidList = GeneralUtility::trimExplode(
',', $conf[
'pidInList'],
true);
6690 array_walk($pidList,
function (&$storagePid) {
6691 if ($storagePid ===
'this') {
6692 $storagePid = $this->getTypoScriptFrontendController()->id;
6694 if ($storagePid > 0) {
6695 $storagePid = -$storagePid;
6698 $expandedPidList = [];
6699 foreach ($pidList as $value) {
6702 $expandedPidList = array_merge(
6703 GeneralUtility::intExplode(
',', $this->getTreeList($value, $conf[
'recursive'])),
6707 $conf[
'pidInList'] = implode(
',', $expandedPidList);
6710 if ((
string)$conf[
'pidInList'] ===
'') {
6711 $conf[
'pidInList'] =
'this';
6714 $queryParts = $this->getQueryConstraints($table, $conf);
6716 $queryBuilder = $connection->createQueryBuilder();
6719 $queryBuilder->getRestrictions()->removeAll();
6720 $queryBuilder->select(
'*')->from($table);
6722 if ($queryParts[
'where']) {
6723 $queryBuilder->where($queryParts[
'where']);
6726 if ($queryParts[
'groupBy']) {
6727 $queryBuilder->groupBy(...$queryParts[
'groupBy']);
6730 if (is_array($queryParts[
'orderBy'])) {
6731 foreach ($queryParts[
'orderBy'] as $orderBy) {
6732 $queryBuilder->addOrderBy(...$orderBy);
6737 if ($conf[
'selectFields']) {
6738 $queryBuilder->selectLiteral($this->sanitizeSelectPart($conf[
'selectFields'], $table));
6743 if ($conf[
'max'] || $conf[
'begin']) {
6745 if (strpos(strtolower($conf[
'begin'] . $conf[
'max']),
'total') !==
false) {
6746 $countQueryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
6747 $countQueryBuilder->getRestrictions()->removeAll();
6748 $countQueryBuilder->count(
'*')
6750 ->where($queryParts[
'where']);
6752 if ($queryParts[
'groupBy']) {
6753 $countQueryBuilder->groupBy(...$queryParts[
'groupBy']);
6757 $count = $countQueryBuilder->execute()->fetchColumn(0);
6758 $conf[
'max'] = str_ireplace(
'total', $count, $conf[
'max']);
6759 $conf[
'begin'] = str_ireplace(
'total', $count, $conf[
'begin']);
6760 }
catch (DBALException $e) {
6761 $this->getTimeTracker()->setTSlogMessage($e->getPrevious()->getMessage());
6767 $conf[
'begin'] = MathUtility::forceIntegerInRange(ceil($this->calc($conf[
'begin'])), 0);
6768 $conf[
'max'] = MathUtility::forceIntegerInRange(ceil($this->calc($conf[
'max'])), 0);
6769 if ($conf[
'begin'] > 0) {
6770 $queryBuilder->setFirstResult($conf[
'begin']);
6772 $queryBuilder->setMaxResults($conf[
'max'] ?: 100000);
6778 if ($conf[
'join']) {
6779 $joinParts = QueryHelper::parseJoin($conf[
'join']);
6780 $queryBuilder->join(
6782 $joinParts[
'tableName'],
6783 $joinParts[
'tableAlias'],
6784 $joinParts[
'joinCondition']
6786 } elseif ($conf[
'leftjoin']) {
6787 $joinParts = QueryHelper::parseJoin($conf[
'leftjoin']);
6788 $queryBuilder->leftJoin(
6790 $joinParts[
'tableName'],
6791 $joinParts[
'tableAlias'],
6792 $joinParts[
'joinCondition']
6794 } elseif ($conf[
'rightjoin']) {
6795 $joinParts = QueryHelper::parseJoin($conf[
'rightjoin']);
6796 $queryBuilder->rightJoin(
6798 $joinParts[
'tableName'],
6799 $joinParts[
'tableAlias'],
6800 $joinParts[
'joinCondition']
6805 $query = $queryBuilder->getSQL();
6808 foreach ($queryMarkers as $marker => $markerValue) {
6811 $query = str_replace(
'###' . $marker .
'###', $markerValue, $query);
6812 foreach ($queryParts as $queryPartKey => &$queryPartValue) {
6813 $queryPartValue = str_replace(
'###' . $marker .
'###', $markerValue, $queryPartValue);
6815 unset($queryPartValue);
6818 return $returnQueryArray ? $this->getQueryArray($queryBuilder) : $query;
6832 protected function getQueryArray(QueryBuilder $queryBuilder)
6839 foreach ($queryBuilder->getQueryPart(
'from') as $from) {
6840 if ($from[
'alias'] ===
null) {
6841 $tableSql = $from[
'table'];
6842 $tableReference = $from[
'table'];
6844 $tableSql = $from[
'table'] .
' ' . $from[
'alias'];
6845 $tableReference = $from[
'alias'];
6848 $knownAliases[$tableReference] =
true;
6850 $fromClauses[$tableReference] = $tableSql . $this->getQueryArrayJoinHelper(
6852 $queryBuilder->getQueryPart(
'join'),
6857 $queryParts[
'SELECT'] = implode(
', ', $queryBuilder->getQueryPart(
'select'));
6858 $queryParts[
'FROM'] = implode(
', ', $fromClauses);
6859 $queryParts[
'WHERE'] = (string)$queryBuilder->getQueryPart(
'where') ?:
'';
6860 $queryParts[
'GROUPBY'] = implode(
', ', $queryBuilder->getQueryPart(
'groupBy'));
6861 $queryParts[
'ORDERBY'] = implode(
', ', $queryBuilder->getQueryPart(
'orderBy'));
6862 if ($queryBuilder->getFirstResult() > 0) {
6863 $queryParts[
'LIMIT'] = $queryBuilder->getFirstResult() .
',' . $queryBuilder->getMaxResults();
6864 } elseif ($queryBuilder->getMaxResults() > 0) {
6865 $queryParts[
'LIMIT'] = $queryBuilder->getMaxResults();
6880 protected function getQueryArrayJoinHelper(
string $fromAlias, array $joinParts, array &$knownAliases): string
6884 if (isset($joinParts[
'join'][$fromAlias])) {
6885 foreach ($joinParts[
'join'][$fromAlias] as $join) {
6886 if (array_key_exists($join[
'joinAlias'], $knownAliases)) {
6887 throw new \RuntimeException(
6888 'Non unique join alias: "' . $join[
'joinAlias'] .
'" found.',
6892 $sql .=
' ' . strtoupper($join[
'joinType'])
6893 .
' JOIN ' . $join[
'joinTable'] .
' ' . $join[
'joinAlias']
6894 .
' ON ' . ((string)$join[
'joinCondition']);
6895 $knownAliases[$join[
'joinAlias']] =
true;
6898 foreach ($joinParts[
'join'][$fromAlias] as $join) {
6899 $sql .= $this->getQueryArrayJoinHelper($join[
'joinAlias'], $joinParts, $knownAliases);
6914 protected function getQueryConstraints(
string $table, array $conf): array
6917 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
6918 $expressionBuilder = $queryBuilder->expr();
6919 $tsfe = $this->getTypoScriptFrontendController();
6922 $enableFieldsIgnore = [];
6929 $isInWorkspace = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect(
'workspace',
'isOffline');
6930 $considerMovePlaceholders = (
6931 $isInWorkspace && $table !==
'pages'
6932 && !empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS'])
6935 if (trim($conf[
'uidInList'])) {
6936 $listArr = GeneralUtility::intExplode(
',', str_replace(
'this', $tsfe->contentPid, $conf[
'uidInList']));
6939 if ($considerMovePlaceholders) {
6940 $constraints[] = (string)$expressionBuilder->orX(
6941 $expressionBuilder->in($table .
'.uid', $listArr),
6942 $expressionBuilder->andX(
6943 $expressionBuilder->eq(
6944 $table .
'.t3ver_state',
6945 (
int)(
string)VersionState::cast(VersionState::MOVE_PLACEHOLDER)
6947 $expressionBuilder->in($table .
'.t3ver_move_id', $listArr)
6951 $constraints[] = (string)$expressionBuilder->in($table .
'.uid', $listArr);
6957 if (strpos($table,
'static_') === 0) {
6961 if (trim($conf[
'pidInList'])) {
6962 $listArr = GeneralUtility::intExplode(
',', str_replace(
'this', $tsfe->contentPid, $conf[
'pidInList']));
6964 $listArr = $this->checkPidArray($listArr);
6965 if (GeneralUtility::inList($conf[
'pidInList'],
'root')) {
6968 if (GeneralUtility::inList($conf[
'pidInList'],
'-1')) {
6970 $enableFieldsIgnore[
'pid'] =
true;
6972 if (!empty($listArr)) {
6973 $constraints[] = $expressionBuilder->in($table .
'.pid', array_map(
'intval', $listArr));
6982 if (!$pid_uid_flag) {
6983 $constraints[] = $expressionBuilder->eq($table .
'.uid', 0);
6986 $where = isset($conf[
'where.']) ? trim($this->stdWrap($conf[
'where'], $conf[
'where.'])) : trim($conf[
'where']);
6988 $constraints[] = QueryHelper::stripLogicalOperatorPrefix($where);
6993 $languageConstraint = $this->getLanguageRestriction($expressionBuilder, $table, $conf, GeneralUtility::makeInstance(Context::class));
6994 if ($languageConstraint !==
null) {
6995 $constraints[] = $languageConstraint;
6999 if ($table ===
'pages') {
7000 $constraints[] = QueryHelper::stripLogicalOperatorPrefix($tsfe->sys_page->where_hid_del);
7001 $constraints[] = QueryHelper::stripLogicalOperatorPrefix($tsfe->sys_page->where_groupAccess);
7003 $constraints[] = QueryHelper::stripLogicalOperatorPrefix($tsfe->sys_page->enableFields($table, -1, $enableFieldsIgnore));
7007 if (count($constraints) !== 0) {
7008 $queryParts[
'where'] = $expressionBuilder->andX(...$constraints);
7011 if (trim($conf[
'groupBy'])) {
7012 $groupBy = isset($conf[
'groupBy.'])
7013 ? trim($this->stdWrap($conf[
'groupBy'], $conf[
'groupBy.']))
7014 : trim($conf[
'groupBy']);
7015 $queryParts[
'groupBy'] = QueryHelper::parseGroupBy($groupBy);
7019 if (trim($conf[
'orderBy'])) {
7020 $orderByString = isset($conf[
'orderBy.'])
7021 ? trim($this->stdWrap($conf[
'orderBy'], $conf[
'orderBy.']))
7022 : trim($conf[
'orderBy']);
7024 $queryParts[
'orderBy'] = QueryHelper::parseOrderBy($orderByString);
7057 protected function getLanguageRestriction(
ExpressionBuilder $expressionBuilder,
string $table, array $conf,
Context $context)
7059 $languageField =
'';
7060 $localizationParentField =
$GLOBALS[
'TCA'][$table][
'ctrl'][
'transOrigPointerField'] ??
null;
7062 if (!empty($conf[
'languageField']) || !isset($conf[
'languageField'])) {
7063 if (isset($conf[
'languageField']) && !empty(
$GLOBALS[
'TCA'][$table][
'columns'][$conf[
'languageField']])) {
7064 $languageField = $conf[
'languageField'];
7065 } elseif (!empty(
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField']) && !empty($localizationParentField)) {
7066 $languageField = $table .
'.' .
$GLOBALS[
'TCA'][$table][
'ctrl'][
'languageField'];
7071 if (empty($languageField)) {
7076 $languageAspect = $context->
getAspect(
'language');
7077 if ($languageAspect->doOverlays() && !empty($localizationParentField)) {
7080 $languageQuery = $expressionBuilder->
in($languageField, [0, -1]);
7083 if (isset($conf[
'includeRecordsWithoutDefaultTranslation']) || $conf[
'includeRecordsWithoutDefaultTranslation.']) {
7084 $includeRecordsWithoutDefaultTranslation = isset($conf[
'includeRecordsWithoutDefaultTranslation.']) ?
7085 $this->stdWrap($conf[
'includeRecordsWithoutDefaultTranslation'], $conf[
'includeRecordsWithoutDefaultTranslation.']) : $conf[
'includeRecordsWithoutDefaultTranslation'];
7086 $includeRecordsWithoutDefaultTranslation = trim($includeRecordsWithoutDefaultTranslation) !==
'';
7089 $includeRecordsWithoutDefaultTranslation = $languageAspect->getOverlayType() === $languageAspect::OVERLAYS_ON_WITH_FLOATING;
7091 if ($includeRecordsWithoutDefaultTranslation) {
7092 $languageQuery = $expressionBuilder->
orX(
7094 $expressionBuilder->
andX(
7095 $expressionBuilder->
eq($table .
'.' . $localizationParentField, 0),
7096 $expressionBuilder->
eq($languageField, $languageAspect->getContentId())
7100 return $languageQuery;
7103 return $expressionBuilder->
in($languageField, [$languageAspect->getContentId(), -1]);
7118 protected function sanitizeSelectPart($selectPart, $table)
7120 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
7123 $matchStart =
'/(^\\s*|,\\s*|' . $table .
'\\.)';
7124 $matchEnd =
'(\\s*,|\\s*$)/';
7125 $necessaryFields = [
'uid',
'pid'];
7126 $wsFields = [
't3ver_state'];
7127 if (isset(
$GLOBALS[
'TCA'][$table]) && !preg_match($matchStart .
'\\*' . $matchEnd, $selectPart) && !preg_match(
'/(count|max|min|avg|sum)\\([^\\)]+\\)|distinct/i', $selectPart)) {
7128 foreach ($necessaryFields as $field) {
7129 $match = $matchStart . $field . $matchEnd;
7130 if (!preg_match($match, $selectPart)) {
7131 $selectPart .=
', ' . $connection->quoteIdentifier($table .
'.' . $field) .
' AS ' . $connection->quoteIdentifier($field);
7134 if (
$GLOBALS[
'TCA'][$table][
'ctrl'][
'versioningWS']) {
7135 foreach ($wsFields as $field) {
7136 $match = $matchStart . $field . $matchEnd;
7137 if (!preg_match($match, $selectPart)) {
7138 $selectPart .=
', ' . $connection->quoteIdentifier($table .
'.' . $field) .
' AS ' . $connection->quoteIdentifier($field);
7154 public function checkPidArray($listArr)
7156 if (!is_array($listArr) || empty($listArr)) {
7160 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
7161 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
7162 $queryBuilder->select(
'uid')
7165 $queryBuilder->expr()->in(
7167 $queryBuilder->createNamedParameter($listArr, Connection::PARAM_INT_ARRAY)
7169 $queryBuilder->expr()->notIn(
7171 $queryBuilder->createNamedParameter(
7172 GeneralUtility::intExplode(
',', $this->checkPid_badDoktypeList,
true),
7173 Connection::PARAM_INT_ARRAY
7178 $result = $queryBuilder->execute();
7179 while ($row = $result->fetch()) {
7180 $outArr[] = $row[
'uid'];
7182 }
catch (DBALException $e) {
7183 $this->getTimeTracker()->setTSlogMessage($e->getMessage() .
': ' . $queryBuilder->getSQL(), 3);
7197 public function checkPid($uid)
7200 if (!isset($this->checkPid_cache[$uid])) {
7201 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
7202 $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
7203 $count = $queryBuilder->count(
'*')
7206 $queryBuilder->expr()->eq(
7208 $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
7210 $queryBuilder->expr()->notIn(
7212 $queryBuilder->createNamedParameter(
7213 GeneralUtility::intExplode(
',', $this->checkPid_badDoktypeList,
true),
7214 Connection::PARAM_INT_ARRAY
7221 $this->checkPid_cache[$uid] = (bool)$count;
7223 return $this->checkPid_cache[$uid];
7236 public function getQueryMarkers($table, $conf)
7238 if (!is_array($conf[
'markers.'])) {
7242 $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
7244 foreach ($conf[
'markers.'] as $dottedMarker => $dummy) {
7245 $marker = rtrim($dottedMarker,
'.');
7246 if ($dottedMarker != $marker .
'.') {
7250 $tempValue = isset($conf[
'markers.'][$dottedMarker])
7251 ? $this->stdWrap($conf[
'markers.'][$dottedMarker][
'value'], $conf[
'markers.'][$dottedMarker])
7252 : $conf[
'markers.'][$dottedMarker][
'value'];
7254 if (is_numeric($tempValue)) {
7255 if ((
int)$tempValue == $tempValue) {
7257 $markerValues[$marker] = (int)$tempValue;
7260 $markerValues[$marker] = (float)$tempValue;
7262 } elseif ($tempValue ===
null) {
7264 $markerValues[$marker] =
'NULL';
7265 } elseif (!empty($conf[
'markers.'][$dottedMarker][
'commaSeparatedList'])) {
7267 $explodeValues = GeneralUtility::trimExplode(
',', $tempValue);
7268 if (count($explodeValues) > 1) {
7271 foreach ($explodeValues as $listValue) {
7272 if (is_numeric($listValue)) {
7273 if ((
int)$listValue == $listValue) {
7274 $tempArray[] = (int)$listValue;
7276 $tempArray[] = (float)$listValue;
7281 if (preg_match(
'/^\'([^\']*)\'$/', $listValue, $matches)) {
7282 $listValue = $matches[1];
7283 } elseif (preg_match(
'/^\\"([^\\"]*)\\"$/', $listValue, $matches)) {
7284 $listValue = $matches[1];
7286 $tempArray[] = $connection->quote($listValue);
7289 $markerValues[$marker] = implode(
',', $tempArray);
7292 $markerValues[$marker] = $connection->quote($tempValue);
7296 $markerValues[$marker] = $connection->quote($tempValue);
7299 return $markerValues;
7318 public function editPanel($content, $conf, $currentRecord =
'', $dataArray = [])
7320 if (!$this->getTypoScriptFrontendController()->isBackendUserLoggedIn()) {
7323 if (!$this->getTypoScriptFrontendController()->displayEditIcons) {
7327 if (!$currentRecord) {
7328 $currentRecord = $this->currentRecord;
7330 if (empty($dataArray)) {
7331 $dataArray = $this->data;
7334 if ($conf[
'newRecordFromTable']) {
7335 $currentRecord = $conf[
'newRecordFromTable'] .
':NEW';
7336 $conf[
'allow'] =
'new';
7337 $checkEditAccessInternals =
false;
7339 $checkEditAccessInternals =
true;
7341 list($table, $uid) = explode(
':', $currentRecord);
7343 $newRecordPid = (int)$conf[
'newRecordInPid'];
7345 if (!$conf[
'onlyCurrentPid'] || $dataArray[
'pid'] == $this->getTypoScriptFrontendController()->id) {
7346 if ($table ===
'pages') {
7349 if ($conf[
'newRecordFromTable']) {
7350 $newUid = $this->getTypoScriptFrontendController()->id;
7351 if ($newRecordPid) {
7352 $newUid = $newRecordPid;
7355 $newUid = -1 * $uid;
7359 if ($table && $this->getFrontendBackendUser()->allowedToEdit($table, $dataArray, $conf, $checkEditAccessInternals) && $this->getFrontendBackendUser()->allowedToEditLanguage($table, $dataArray)) {
7360 $editClass =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'typo3/classes/class.frontendedit.php'][
'edit'];
7362 $edit = GeneralUtility::makeInstance($editClass);
7363 $allowedActions = $this->getFrontendBackendUser()->getAllowedEditActions($table, $conf, $dataArray[
'pid']);
7364 $content = $edit->editPanel($content, $conf, $currentRecord, $dataArray, $table, $allowedActions, $newUid, []);
7382 public function editIcons($content, $params, array $conf = [], $currentRecord =
'', $dataArray = [], $addUrlParamStr =
'')
7384 if (!$this->getTypoScriptFrontendController()->isBackendUserLoggedIn()) {
7387 if (!$this->getTypoScriptFrontendController()->displayFieldEditIcons) {
7390 if (!$currentRecord) {
7391 $currentRecord = $this->currentRecord;
7393 if (empty($dataArray)) {
7394 $dataArray = $this->data;
7397 list($currentRecordTable, $currentRecordUID) = explode(
':', $currentRecord);
7398 list($fieldList, $table) = array_reverse(GeneralUtility::trimExplode(
':', $params,
true));
7401 $table = $currentRecordTable;
7402 } elseif ($table != $currentRecordTable) {
7407 $editUid = $dataArray[
'_LOCALIZED_UID'] ?: $currentRecordUID;
7409 if (!array_key_exists(
'allow', $conf)) {
7410 $conf[
'allow'] =
'edit';
7412 if ($table && $this->getFrontendBackendUser()->allowedToEdit($table, $dataArray, $conf,
true) && $fieldList && $this->getFrontendBackendUser()->allowedToEditLanguage($table, $dataArray)) {
7413 $editClass =
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'typo3/classes/class.frontendedit.php'][
'edit'];
7415 $edit = GeneralUtility::makeInstance($editClass);
7416 $content = $edit->editIcons($content, $params, $conf, $currentRecord, $dataArray, $addUrlParamStr, $table, $editUid, $fieldList);
7431 public function isDisabled($table, $row)
7433 $tsfe = $this->getTypoScriptFrontendController();
7434 $enablecolumns =
$GLOBALS[
'TCA'][$table][
'ctrl'][
'enablecolumns'];
7435 return $enablecolumns[
'disabled'] && $row[$enablecolumns[
'disabled']]
7436 || $enablecolumns[
'fe_group'] && $tsfe->simUserGroup && (int)$row[$enablecolumns[
'fe_group']] === (
int)$tsfe->simUserGroup
7437 || $enablecolumns[
'starttime'] && $row[$enablecolumns[
'starttime']] >
$GLOBALS[
'EXEC_TIME']
7438 || $enablecolumns[
'endtime'] && $row[$enablecolumns[
'endtime']] && $row[$enablecolumns[
'endtime']] <
$GLOBALS[
'EXEC_TIME'];
7446 protected function getResourceFactory()
7448 return ResourceFactory::getInstance();
7458 protected function getEnvironmentVariable($key)
7460 return GeneralUtility::getIndpEnv($key);
7470 protected function getFromCache(array $configuration)
7474 if ($this->getTypoScriptFrontendController()->no_cache) {
7477 $cacheKey = $this->calculateCacheKey($configuration);
7478 if (!empty($cacheKey)) {
7480 $cacheFrontend = GeneralUtility::makeInstance(CacheManager::class)
7481 ->getCache(
'cache_hash');
7482 $content = $cacheFrontend->get($cacheKey);
7493 protected function calculateCacheLifetime(array $configuration)
7495 $lifetimeConfiguration = $configuration[
'lifetime'] ??
'';
7496 $lifetimeConfiguration = isset($configuration[
'lifetime.'])
7497 ? $this->stdWrap($lifetimeConfiguration, $configuration[
'lifetime.'])
7498 : $lifetimeConfiguration;
7501 if (strtolower($lifetimeConfiguration) ===
'unlimited') {
7503 } elseif ($lifetimeConfiguration > 0) {
7504 $lifetime = (int)$lifetimeConfiguration;
7515 protected function calculateCacheTags(array $configuration)
7517 $tags = $configuration[
'tags'] ??
'';
7518 $tags = isset($configuration[
'tags.'])
7519 ? $this->stdWrap($tags, $configuration[
'tags.'])
7521 return empty($tags) ? [] : GeneralUtility::trimExplode(
',', $tags);
7530 protected function calculateCacheKey(array $configuration)
7532 $key = $configuration[
'key'] ??
'';
7533 return isset($configuration[
'key.'])
7534 ? $this->stdWrap($key, $configuration[
'key.'])
7543 protected function getFrontendBackendUser()
7551 protected function getTimeTracker()
7553 return GeneralUtility::makeInstance(TimeTracker::class);
7559 protected function getTypoScriptFrontendController()
7561 return $this->typoScriptFrontendController ?:
$GLOBALS[
'TSFE'];
7573 protected function resolveAnchorLink(
string $linkText, array $conf): string
7575 $anchorTag =
'<a ' . $this->getATagParams($conf) .
'>';
7576 $aTagParams = GeneralUtility::get_tag_attributes($anchorTag);
7578 if (isset($aTagParams[
'id']) || isset($aTagParams[
'name'])) {
7579 return $anchorTag . $linkText .
'</a>';
7585 protected function shallDebug(): bool
7587 $tsfe = $this->getTypoScriptFrontendController();
7588 if ($tsfe !==
null && isset($tsfe->config[
'config'][
'debug'])) {
7589 return (
bool)($tsfe->config[
'config'][
'debug']);
7591 return !empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'debug']);