50 'menuNumber' =>
'Using $menuNumber of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
51 'entryLevel' =>
'Using $entryLevel of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
52 'spacerIDList' =>
'Using $spacerIDList of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
53 'doktypeExcludeList' =>
'Using $doktypeExcludeList of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
54 'alwaysActivePIDlist' =>
'Using $alwaysActivePIDlist of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
55 'imgNamePrefix' =>
'Using $imgNamePrefix of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
56 'imgNameNotRandom' =>
'Using $imgNameNotRandom of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
57 'debug' =>
'Using $debug of cObject HMENU from the outside is discouraged, as this variable is not in use anymore and will be removed in TYPO3 v10.0.',
58 'GMENU_fixKey' =>
'Using $GMENU_fixKey of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
59 'MP_array' =>
'Using $MP_array of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
60 'conf' =>
'Using $conf of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
61 'mconf' =>
'Using $mconf of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
62 'tmpl' =>
'Using $tmpl of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
63 'sys_page' =>
'Using $sys_page of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
64 'id' =>
'Using $id of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
65 'nextActive' =>
'Using $nextActive of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
66 'menuArr' =>
'Using $menuArr of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
67 'hash' =>
'Using $hash of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
68 'result' =>
'Using $result of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
69 'rL_uidRegister' =>
'Using $rL_uidRegister of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
70 'INPfixMD5' =>
'Using $INPfixMD5 of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
71 'I' =>
'Using $I of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
72 'WMresult' =>
'Using $WMresult of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
73 'WMfreezePrefix' =>
'Using $WMfreezePrefix of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
74 'WMmenuItems' =>
'Using $WMmenuItems of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
75 'WMsubmenuObjSuffixes' =>
'Using $WMsubmenuObjSuffixes of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
76 'WMextraScript' =>
'Using $WMextraScript of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
77 'WMcObj' =>
'Using $WMcObj of cObject HMENU is discouraged, as all graphical-related functionality will be removed in TYPO3 v10.0.',
78 'alternativeMenuTempArray' =>
'Using $alternativeMenuTempArray of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
79 'nameAttribute' =>
'Using $nameAttribute of cObject HMENU from the outside is discouraged, as this variable is only used for internal storage.',
83 'subMenu' =>
'Using subMenu() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
84 'link' =>
'Using link() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
85 'procesItemStates' =>
'Using procesItemStates() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
86 'changeLinksForAccessRestrictedPages' =>
'Using changeLinksForAccessRestrictedPages() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
87 'isNext' =>
'Using isNext() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
88 'isActive' =>
'Using isActive() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
89 'isCurrent' =>
'Using isCurrent() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
90 'isSubMenu' =>
'Using isSubMenu() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
91 'isItemState' =>
'Using isItemState() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
92 'accessKey' =>
'Using accessKey() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
93 'userProcess' =>
'Using userProcess() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
94 'setATagParts' =>
'Using setATagParts() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
95 'getPageTitle' =>
'Using getPageTitle() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
96 'getMPvar' =>
'Using getMPvar() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
97 'getDoktypeExcludeWhere' =>
'Using getDoktypeExcludeWhere() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
98 'getBannedUids' =>
'Using getBannedUids() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
99 'menuTypoLink' =>
'Using menuTypoLink() within HMENU is discouraged, as this is internal functionality that should not be exposed to the public.',
100 'extProc_RO' =>
'Using extProc_RO() within HMENU extensions is discouraged, as rollover functionality will be removed in TYPO3 v10.0.',
101 'extProc_init' =>
'Using extProc_init() within HMENU extensions is discouraged, as extending HMENU should only happens via userFunc options.',
102 'extProc_beforeLinking' =>
'Using extProc_beforeLinking() within HMENU extensions is discouraged, as extending HMENU should only happens via userFunc options.',
103 'extProc_afterLinking' =>
'Using extProc_afterLinking() within HMENU extensions is discouraged, as extending HMENU should only happens via userFunc options.',
104 'extProc_beforeAllWrap' =>
'Using extProc_beforeAllWrap() within HMENU extensions is discouraged, as extending HMENU should only happens via userFunc options.',
105 'extProc_finish' =>
'Using extProc_finish() within HMENU extensions is discouraged, as extending HMENU should only happens via userFunc options.',
106 'getBeforeAfter' =>
'Using getBeforeAfter() within HMENU extensions is discouraged, as extending HMENU should only happens via userFunc options.',
332 $this->mconf =
$conf[$this->menuNumber . $objSuffix .
'.'];
333 $this->
debug = !empty($tsfe->config[
'config'][
'debug']);
334 $this->WMcObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
336 switch ($tsfe->xhtmlDoctype) {
345 $this->nameAttribute =
'id';
348 $this->nameAttribute =
'name';
351 if ($this->conf[$this->menuNumber . $objSuffix] && is_object(
$tmpl) && is_object(
$sys_page)) {
355 if (trim($this->conf[
'alwaysActivePIDlist']) || isset($this->conf[
'alwaysActivePIDlist.'])) {
356 if (isset($this->conf[
'alwaysActivePIDlist.'])) {
357 $this->conf[
'alwaysActivePIDlist'] = $this->parent_cObj->stdWrap(
358 $this->conf[
'alwaysActivePIDlist'],
359 $this->conf[
'alwaysActivePIDlist.']
362 $this->alwaysActivePIDlist = GeneralUtility::intExplode(
',', $this->conf[
'alwaysActivePIDlist']);
365 $includeNotInMenu = $this->conf[
'includeNotInMenu'];
366 $includeNotInMenuConf = $this->conf[
'includeNotInMenu.'] ??
null;
367 $this->conf[
'includeNotInMenu'] = is_array($includeNotInMenuConf)
368 ? $this->parent_cObj->stdWrap($includeNotInMenu, $includeNotInMenuConf)
371 if ($this->conf[
'excludeDoktypes']) {
372 $this->doktypeExcludeList = implode(
',', GeneralUtility::intExplode(
',', $this->conf[
'excludeDoktypes']));
375 $this->entryLevel = $this->parent_cObj->getKey(
376 isset(
$conf[
'entryLevel.']) ? $this->parent_cObj->stdWrap(
380 $this->tmpl->rootLine
385 $this->
id = (int)
$id;
388 $this->
id = (int)$this->tmpl->rootLine[$this->entryLevel][
'uid'];
391 foreach ($this->tmpl->rootLine as
$entryLevel => $levelRec) {
393 if ($levelRec[
'_MP_PARAM'] && $levelRec[
'_MOUNT_OL']) {
394 $this->MP_array[] = $levelRec[
'_MP_PARAM'];
401 if ($levelRec[
'_MP_PARAM'] && !$levelRec[
'_MOUNT_OL']) {
402 $this->MP_array[] = $levelRec[
'_MP_PARAM'];
407 if ($this->
id <= 0) {
412 $mount_info = $this->sys_page->getMountPointInfo($this->
id);
413 if (is_array($mount_info)) {
414 $this->MP_array[] = $mount_info[
'MPvar'];
415 $this->
id = $mount_info[
'mount_pid'];
419 if ($this->rL_uidRegister ===
null) {
420 $this->rL_uidRegister = [];
422 foreach ($this->tmpl->rootLine as $v_rl) {
424 if ($v_rl[
'_MP_PARAM'] && $v_rl[
'_MOUNT_OL']) {
425 $rl_MParray[] = $v_rl[
'_MP_PARAM'];
428 $this->rL_uidRegister[] =
'ITEM:' . $v_rl[
'uid'] .
431 ?
':' . implode(
',', $rl_MParray)
435 if ($v_rl[
'_MP_PARAM'] && !$v_rl[
'_MOUNT_OL']) {
436 $rl_MParray[] = $v_rl[
'_MP_PARAM'];
443 if ($this->conf[
'special'] ===
'directory') {
444 $value = isset($this->conf[
'special.'][
'value.']) ? $this->parent_cObj->stdWrap(
445 $this->conf[
'special.'][
'value'],
446 $this->conf[
'special.'][
'value.']
447 ) : $this->conf[
'special.'][
'value'];
449 $value = $tsfe->page[
'uid'];
451 $directoryLevel = (int)$tsfe->tmpl->getRootlineLevel($value);
457 if (is_array($this->tmpl->rootLine[$currentLevel])) {
459 if (empty($nextMParray) && !$this->tmpl->rootLine[$currentLevel][
'_MOUNT_OL'] && $currentLevel > 0) {
462 $parentRecord = $this->tmpl->rootLine[$currentLevel - 1];
463 if (isset($parentRecord[
'_MP_PARAM'])) {
464 $nextMParray[] = $parentRecord[
'_MP_PARAM'];
468 if ($this->tmpl->rootLine[$currentLevel][
'_MOUNT_OL']) {
469 $nextMParray[] = $this->tmpl->rootLine[$currentLevel][
'_MP_PARAM'];
471 $this->nextActive = $this->tmpl->rootLine[$currentLevel][
'uid'] .
474 ?
':' . implode(
',', $nextMParray)
478 $this->nextActive =
'';
481 if ($this->mconf[
'imgNamePrefix']) {
482 $this->imgNamePrefix = $this->mconf[
'imgNamePrefix'];
484 $this->imgNameNotRandom = $this->mconf[
'imgNameNotRandom'];
505 $this->useCacheHash =
false;
508 $SAVED_where_groupAccess =
'';
509 if ($this->mconf[
'showAccessRestrictedPages']) {
511 $SAVED_where_groupAccess = $this->sys_page->where_groupAccess;
513 $this->sys_page->where_groupAccess =
'';
520 $minItems = (int)($this->mconf[
'minItems'] ?: $this->conf[
'minItems']);
521 $maxItems = (int)($this->mconf[
'maxItems'] ?: $this->conf[
'maxItems']);
522 $begin = $this->parent_cObj->calc($this->mconf[
'begin'] ? $this->mconf[
'begin'] : $this->conf[
'begin']);
523 $minItemsConf = $this->mconf[
'minItems.'] ?? $this->conf[
'minItems.'] ??
null;
524 $minItems = is_array($minItemsConf) ? $this->parent_cObj->stdWrap($minItems, $minItemsConf) : $minItems;
525 $maxItemsConf = $this->mconf[
'maxItems.'] ?? $this->conf[
'maxItems.'] ??
null;
526 $maxItems = is_array($maxItemsConf) ? $this->parent_cObj->stdWrap($maxItems, $maxItemsConf) : $maxItems;
527 $beginConf = $this->mconf[
'begin.'] ?? $this->conf[
'begin.'] ??
null;
528 $begin = is_array($beginConf) ? $this->parent_cObj->stdWrap($begin, $beginConf) : $begin;
532 foreach ($menuItems as $data) {
533 $spacer = GeneralUtility::inList($this->spacerIDList, $data[
'doktype']) || $data[
'ITEM_STATE'] ===
'SPC';
538 if ($begin <= $c_b) {
540 $this->menuArr[$c][
'isSpacer'] = $spacer;
542 if ($maxItems && $c >= $maxItems) {
550 while ($c < $minItems) {
551 $this->menuArr[$c] = [
559 if ($this->mconf[
'itemArrayProcFunc']) {
560 $this->menuArr = $this->
userProcess(
'itemArrayProcFunc', $this->menuArr);
565 serialize($this->menuArr) .
566 serialize($this->mconf) .
567 serialize($this->tmpl->rootLine) .
568 serialize($this->MP_array)
571 if ($this->conf[
'cache_period']) {
572 $cacheTimeout = $this->conf[
'cache_period'];
577 $cachedData = $cache->get($this->hash);
578 if (!is_array($cachedData)) {
580 $cache->set($this->hash, $this->result, [
'ident_MENUDATA'], (
int)$cacheTimeout);
582 $this->result = $cachedData;
585 if ($this->mconf[
'showAccessRestrictedPages']) {
587 $this->sys_page->where_groupAccess = $SAVED_where_groupAccess;
618 foreach ($pages as $aPage) {
620 $filteredPages[$aPage[
'uid']] = $aPage;
623 return $filteredPages;
634 $alternativeSortingField = trim($this->mconf[
'alternativeSortingField']) ?:
'sorting';
637 $additionalWhere = $this->mconf[
'additionalWhere'] ??
'';
638 if (isset($this->mconf[
'additionalWhere.'])) {
639 $additionalWhere = $this->parent_cObj->stdWrap($additionalWhere, $this->mconf[
'additionalWhere.']);
643 if ($this->menuNumber == 1 && $this->conf[
'special']) {
644 $value = isset($this->conf[
'special.'][
'value.'])
645 ? $this->parent_cObj->stdWrap($this->conf[
'special.'][
'value'], $this->conf[
'special.'][
'value.'])
646 : $this->conf[
'special.'][
'value'];
647 switch ($this->conf[
'special']) {
658 $menuItems = $this->prepareMenuItemsForListMenu($value);
663 $this->mconf[
'alternativeSortingField'] ?:
false
669 $this->mconf[
'alternativeSortingField'] ?:
false
674 $categoryMenuUtility = GeneralUtility::makeInstance(CategoryMenuUtility::class);
675 $menuItems = $categoryMenuUtility->collectPages($value, $this->conf[
'special.'], $this);
684 if ($this->mconf[
'sectionIndex']) {
685 $sectionIndexes = [];
686 foreach ($menuItems as $page) {
687 $sectionIndexes = $sectionIndexes + $this->
sectionIndex($alternativeSortingField, $page[
'uid']);
689 $menuItems = $sectionIndexes;
691 } elseif (is_array($this->alternativeMenuTempArray)) {
694 } elseif ($this->mconf[
'sectionIndex']) {
698 $menuItems = $this->sys_page->getMenu($this->
id,
'*', $alternativeSortingField, $additionalWhere);
712 $menuItems = $this->parent_cObj->callUserFunction(
713 $this->conf[
'special.'][
'userFunc'],
714 array_merge($this->conf[
'special.'], [
'value' => $specialValue,
'_altSortField' => $sortingField]),
717 if (!is_array($menuItems)) {
734 $currentPageWithNoOverlay = $this->sys_page->getRawRecord(
'pages', $tsfe->page[
'uid']);
736 if ($specialValue ===
'auto') {
738 $languages = $site->getLanguages();
751 $lRecs = $this->sys_page->getPageOverlay($tsfe->page[
'uid'], $sUid);
756 if (GeneralUtility::hideIfNotTranslated($tsfe->page[
'l18n_cfg']) && $sUid &&
757 empty($lRecs) || GeneralUtility::hideIfDefaultLanguage($tsfe->page[
'l18n_cfg']) &&
758 (!$sUid || empty($lRecs)) ||
759 !$this->conf[
'special.'][
'normalWhenNoLanguage'] && $sUid && empty($lRecs)
761 $iState = $currentLanguageId == $sUid ?
'USERDEF2' :
'USERDEF1';
763 $iState = $currentLanguageId == $sUid ?
'ACT' :
'NO';
765 if ($this->conf[
'addQueryString']) {
766 $getVars = $this->parent_cObj->getQueryArguments(
767 $this->conf[
'addQueryString.'],
773 $getVars =
'&L=' . $sUid;
776 $menuItems[] = array_merge(
777 array_merge($currentPageWithNoOverlay, $lRecs),
779 'ITEM_STATE' => $iState,
780 '_ADD_GETVARS' => $getVars,
799 if ($specialValue ==
'') {
800 $specialValue = $tsfe->page[
'uid'];
802 $items = GeneralUtility::intExplode(
',', $specialValue);
803 $pageLinkBuilder = GeneralUtility::makeInstance(PageLinkBuilder::class, $this->parent_cObj);
804 foreach ($items as
$id) {
805 $MP = $pageLinkBuilder->getMountPointParameterFromRootPointMaps(
$id);
807 $mount_info = $this->sys_page->getMountPointInfo(
$id);
808 if (is_array($mount_info)) {
809 if ($mount_info[
'overlay']) {
811 $MP = $pageLinkBuilder->getMountPointParameterFromRootPointMaps((
int)$mount_info[
'mount_pid']);
812 $MP = $MP ? $MP : $mount_info[
'MPvar'];
814 $MP = ($MP ? $MP .
',' :
'') . $mount_info[
'MPvar'];
816 $id = $mount_info[
'mount_pid'];
819 $statement = $this->parent_cObj->exec_getQuery(
'pages', [
'pidInList' =>
$id,
'orderBy' => $sortingField]);
820 while ($row = $statement->fetch()) {
826 if ($row[
'l10n_parent'] > 0 && !isset($row[
'_PAGES_OVERLAY'])) {
827 $row = $this->sys_page->getPage($row[
'l10n_parent'],
true);
829 $tsfe->sys_page->versionOL(
'pages', $row,
true);
832 $mount_info = $this->sys_page->getMountPointInfo($row[
'uid'], $row);
834 if (is_array($mount_info) && $mount_info[
'overlay']) {
837 $mp_row = $this->sys_page->getPage($mount_info[
'mount_pid']);
838 if (!empty($mp_row)) {
840 $row[
'_MP_PARAM'] = $mount_info[
'MPvar'];
850 $row[
'_MP_PARAM'] = $MP . ($row[
'_MP_PARAM'] ?
',' . $row[
'_MP_PARAM'] :
'');
852 $menuItems[] = $this->sys_page->getPageOverlay($row);
867 protected function prepareMenuItemsForListMenu($specialValue)
870 if ($specialValue ==
'') {
873 $skippedEnableFields = [];
874 if (!empty($this->mconf[
'showAccessRestrictedPages'])) {
875 $skippedEnableFields = [
'fe_group' => 1];
878 $loadDB = GeneralUtility::makeInstance(RelationHandler::class);
879 $loadDB->setFetchAllFields(
true);
880 $loadDB->start($specialValue,
'pages');
881 $loadDB->additionalWhere[
'pages'] = $this->sys_page->enableFields(
'pages', -1, $skippedEnableFields);
882 $loadDB->getFromDB();
883 $pageLinkBuilder = GeneralUtility::makeInstance(PageLinkBuilder::class, $this->parent_cObj);
884 foreach ($loadDB->itemArray as $val) {
885 $MP = $pageLinkBuilder->getMountPointParameterFromRootPointMaps((
int)$val[
'id']);
887 $mount_info = $this->sys_page->getMountPointInfo($val[
'id']);
889 if (is_array($mount_info) && $mount_info[
'overlay']) {
892 $mp_row = $this->sys_page->getPage($mount_info[
'mount_pid']);
893 if (!empty($mp_row)) {
895 $row[
'_MP_PARAM'] = $mount_info[
'MPvar'];
897 if ($mount_info[
'overlay']) {
898 $MP = $pageLinkBuilder->getMountPointParameterFromRootPointMaps((
int)$mount_info[
'mount_pid']);
900 unset($row[
'_MP_PARAM']);
909 $row = $loadDB->results[
'pages'][$val[
'id']];
912 if (isset($row) && is_array($row)) {
913 $this->sys_page->versionOL(
'pages', $row,
true);
916 if (isset($row) && is_array($row)) {
918 $row[
'_MP_PARAM'] = $MP . ($row[
'_MP_PARAM'] ?
',' . $row[
'_MP_PARAM'] :
'');
920 $menuItems[] = $this->sys_page->getPageOverlay($row);
937 if ($specialValue ==
'') {
938 $specialValue = $tsfe->page[
'uid'];
940 $items = GeneralUtility::intExplode(
',', $specialValue);
948 $maxAge = (int)$this->parent_cObj->calc($this->conf[
'special.'][
'maxAge']);
953 $mode = $this->conf[
'special.'][
'mode'];
957 foreach ($items as
$id) {
959 if ($beginAtLevel > 0) {
960 $id_list_arr[] = $this->parent_cObj->getTreeList(
$id, $depth - 1 + $beginAtLevel, $beginAtLevel - 1);
962 $id_list_arr[] = $this->parent_cObj->getTreeList(-1 *
$id, $depth - 1 + $beginAtLevel, $beginAtLevel - 1);
965 $id_list = implode(
',', $id_list_arr);
969 $sortField =
'starttime';
973 $sortField =
'lastUpdated';
976 $sortField =
'tstamp';
979 $sortField =
'crdate';
982 $sortField =
'SYS_LASTCHANGED';
984 $extraWhere = ($this->conf[
'includeNotInMenu'] ?
'' :
' AND pages.nav_hide=0') . $this->
getDoktypeExcludeWhere();
985 if ($this->conf[
'special.'][
'excludeNoSearchPages']) {
986 $extraWhere .=
' AND pages.no_search=0';
989 $extraWhere .=
' AND ' . $sortField .
'>' . (
$GLOBALS[
'SIM_ACCESS_TIME'] - $maxAge);
991 $statement = $this->parent_cObj->exec_getQuery(
'pages', [
993 'uidInList' => $id_list,
994 'where' => $sortField .
'>=0' . $extraWhere,
995 'orderBy' => $sortingField ?: $sortField .
' DESC',
998 while ($row = $statement->fetch()) {
1004 if ($row[
'l10n_parent'] > 0 && !isset($row[
'_PAGES_OVERLAY'])) {
1005 $row = $this->sys_page->getPage($row[
'l10n_parent'],
true);
1007 $tsfe->sys_page->versionOL(
'pages', $row,
true);
1008 if (is_array($row)) {
1009 $menuItems[$row[
'uid']] = $this->sys_page->getPageOverlay($row);
1027 [$specialValue] = GeneralUtility::intExplode(
',', $specialValue);
1028 if (!$specialValue) {
1029 $specialValue = $tsfe->page[
'uid'];
1031 if ($this->conf[
'special.'][
'setKeywords'] || $this->conf[
'special.'][
'setKeywords.']) {
1032 $kw = isset($this->conf[
'special.'][
'setKeywords.']) ? $this->parent_cObj->stdWrap($this->conf[
'special.'][
'setKeywords'], $this->conf[
'special.'][
'setKeywords.']) : $this->conf[
'special.'][
'setKeywords'];
1035 $value_rec = $this->sys_page->getPage($specialValue);
1036 $kfieldSrc = $this->conf[
'special.'][
'keywordsField.'][
'sourceField'] ? $this->conf[
'special.'][
'keywordsField.'][
'sourceField'] :
'keywords';
1038 $kw = trim($this->parent_cObj->keywords($value_rec[$kfieldSrc]));
1041 $mode = $this->conf[
'special.'][
'mode'];
1044 $sortField =
'starttime';
1048 $sortField =
'lastUpdated';
1051 $sortField =
'tstamp';
1054 $sortField =
'crdate';
1057 $sortField =
'SYS_LASTCHANGED';
1068 $eLevel = $this->parent_cObj->getKey(
1069 isset($this->conf[
'special.'][
'entryLevel.'])
1070 ? $this->parent_cObj->stdWrap($this->conf[
'special.'][
'entryLevel'], $this->conf[
'special.'][
'entryLevel.'])
1071 : $this->conf[
'special.'][
'entryLevel'],
1072 $this->tmpl->rootLine
1074 $startUid = (int)$this->tmpl->rootLine[$eLevel][
'uid'];
1076 $kfield =
'keywords';
1077 if ($this->conf[
'special.'][
'keywordsField']) {
1078 [$kfield] = explode(
' ', trim($this->conf[
'special.'][
'keywordsField']));
1081 if ($kw && $startUid) {
1083 $id_list = $this->parent_cObj->getTreeList(-1 * $startUid, $depth - 1 + $bA, $bA - 1);
1084 $kwArr = GeneralUtility::trimExplode(
',', $kw,
true);
1085 $keyWordsWhereArr = [];
1086 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
'pages');
1087 foreach ($kwArr as $word) {
1088 $keyWordsWhereArr[] = $queryBuilder->expr()->like(
1090 $queryBuilder->createNamedParameter(
1091 '%' . $queryBuilder->escapeLikeWildcards($word) .
'%',
1100 $queryBuilder->expr()->in(
1102 GeneralUtility::intExplode(
',', $id_list,
true)
1104 $queryBuilder->expr()->neq(
1106 $queryBuilder->createNamedParameter($specialValue, \PDO::PARAM_INT)
1110 if (count($keyWordsWhereArr) !== 0) {
1111 $queryBuilder->andWhere($queryBuilder->expr()->orX(...$keyWordsWhereArr));
1114 if ($this->doktypeExcludeList) {
1115 $queryBuilder->andWhere(
1116 $queryBuilder->expr()->notIn(
1118 GeneralUtility::intExplode(
',', $this->doktypeExcludeList,
true)
1123 if (!$this->conf[
'includeNotInMenu']) {
1124 $queryBuilder->andWhere($queryBuilder->expr()->eq(
'pages.nav_hide', 0));
1127 if ($this->conf[
'special.'][
'excludeNoSearchPages']) {
1128 $queryBuilder->andWhere($queryBuilder->expr()->eq(
'pages.no_search', 0));
1132 $queryBuilder->setMaxResults($limit);
1135 if ($sortingField) {
1136 $queryBuilder->orderBy($sortingField);
1138 $queryBuilder->orderBy($sortField,
'desc');
1141 $result = $queryBuilder->execute();
1143 $tsfe->sys_page->versionOL(
'pages', $row,
true);
1144 if (is_array($row)) {
1145 $menuItems[$row[
'uid']] = $this->sys_page->getPageOverlay($row);
1161 $range = isset($this->conf[
'special.'][
'range.'])
1162 ? $this->parent_cObj->stdWrap($this->conf[
'special.'][
'range'], $this->conf[
'special.'][
'range.'])
1163 : $this->conf[
'special.'][
'range'];
1164 $begin_end = explode(
'|', $range);
1165 $begin_end[0] = (int)$begin_end[0];
1169 $beginKey = $this->parent_cObj->getKey($begin_end[0], $this->tmpl->rootLine);
1170 $endKey = $this->parent_cObj->getKey($begin_end[1], $this->tmpl->rootLine);
1171 if ($endKey < $beginKey) {
1172 $endKey = $beginKey;
1175 foreach ($this->tmpl->rootLine as $k_rl => $v_rl) {
1177 if ($v_rl[
'_MP_PARAM'] && $v_rl[
'_MOUNT_OL']) {
1178 $rl_MParray[] = $v_rl[
'_MP_PARAM'];
1181 if ($k_rl >= $beginKey && $k_rl <= $endKey) {
1183 $menuItems[$temp_key] = $this->sys_page->getPage($v_rl[
'uid']);
1184 if (!empty($menuItems[$temp_key])) {
1186 if (!$menuItems[$temp_key][
'target']) {
1187 $menuItems[$temp_key][
'target'] = $this->conf[
'special.'][
'targets.'][$k_rl];
1188 $menuItems[$temp_key][
'_MP_PARAM'] = implode(
',', $rl_MParray);
1191 unset($menuItems[$temp_key]);
1195 if ($v_rl[
'_MP_PARAM'] && !$v_rl[
'_MOUNT_OL']) {
1196 $rl_MParray[] = $v_rl[
'_MP_PARAM'];
1200 if (isset($this->conf[
'special.'][
'reverseOrder']) && $this->conf[
'special.'][
'reverseOrder']) {
1201 $menuItems = array_reverse($menuItems);
1217 [$specialValue] = GeneralUtility::intExplode(
',', $specialValue);
1218 if (!$specialValue) {
1222 if ($specialValue != $this->tmpl->rootLine[0][
'uid']) {
1225 $value_rec = $this->sys_page->getPage($specialValue);
1227 if ($value_rec[
'pid']) {
1229 $recArr[
'up'] = $this->sys_page->getPage($value_rec[
'pid']);
1232 if ($recArr[
'up'][
'pid'] && $value_rec[
'pid'] != $this->tmpl->rootLine[0][
'uid']) {
1234 $recArr[
'index'] = $this->sys_page->getPage($recArr[
'up'][
'pid']);
1237 $additionalWhere .= ($this->conf[
'includeNotInMenu'] ?
'' :
' AND pages.nav_hide=0') . $this->
getDoktypeExcludeWhere();
1238 if ($this->conf[
'special.'][
'excludeNoSearchPages']) {
1239 $additionalWhere .=
' AND pages.no_search=0';
1242 $prevnext_menu = $this->
removeInaccessiblePages($this->sys_page->getMenu($value_rec[
'pid'],
'*', $sortingField, $additionalWhere));
1245 foreach ($prevnext_menu as $k_b => $v_b) {
1247 $recArr[
'next'] = $v_b;
1250 if ($v_b[
'uid'] == $specialValue) {
1252 $recArr[
'prev'] = $prevnext_menu[$lastKey];
1259 $recArr[
'first'] = reset($prevnext_menu);
1260 $recArr[
'last'] = end($prevnext_menu);
1263 if (!empty($recArr[
'index'][
'uid'])) {
1264 $prevnextsection_menu = $this->
removeInaccessiblePages($this->sys_page->getMenu($recArr[
'index'][
'uid'],
'*', $sortingField, $additionalWhere));
1267 foreach ($prevnextsection_menu as $k_b => $v_b) {
1269 $sectionRec_temp = $this->
removeInaccessiblePages($this->sys_page->getMenu($v_b[
'uid'],
'*', $sortingField, $additionalWhere));
1270 if (!empty($sectionRec_temp)) {
1271 $recArr[
'nextsection'] = reset($sectionRec_temp);
1272 $recArr[
'nextsection_last'] = end($sectionRec_temp);
1276 if ($v_b[
'uid'] == $value_rec[
'pid']) {
1278 $sectionRec_temp = $this->
removeInaccessiblePages($this->sys_page->getMenu($prevnextsection_menu[$lastKey][
'uid'],
'*', $sortingField, $additionalWhere));
1279 if (!empty($sectionRec_temp)) {
1280 $recArr[
'prevsection'] = reset($sectionRec_temp);
1281 $recArr[
'prevsection_last'] = end($sectionRec_temp);
1289 if ($this->conf[
'special.'][
'items.'][
'prevnextToSection']) {
1290 if (!is_array($recArr[
'prev']) && is_array($recArr[
'prevsection_last'])) {
1291 $recArr[
'prev'] = $recArr[
'prevsection_last'];
1293 if (!is_array($recArr[
'next']) && is_array($recArr[
'nextsection'])) {
1294 $recArr[
'next'] = $recArr[
'nextsection'];
1297 $items = explode(
'|', $this->conf[
'special.'][
'items']);
1299 foreach ($items as $k_b => $v_b) {
1300 $v_b = strtolower(trim($v_b));
1301 if ((
int)$this->conf[
'special.'][$v_b .
'.'][
'uid']) {
1302 $recArr[$v_b] = $this->sys_page->getPage((
int)$this->conf[
'special.'][$v_b .
'.'][
'uid']);
1304 if (is_array($recArr[$v_b])) {
1305 $menuItems[$c] = $recArr[$v_b];
1306 if ($this->conf[
'special.'][$v_b .
'.'][
'target']) {
1307 $menuItems[$c][
'target'] = $this->conf[
'special.'][$v_b .
'.'][
'target'];
1309 $tmpSpecialFields = $this->conf[
'special.'][$v_b .
'.'][
'fields.'];
1310 if (is_array($tmpSpecialFields)) {
1311 foreach ($tmpSpecialFields as $fk => $val) {
1312 $menuItems[$c][$fk] = $val;
1329 $parameters = GeneralUtility::explodeUrl2Array($queryString);
1330 if (!empty($parameters)) {
1331 if (!isset($parameters[
'id'])) {
1335 $cacheHashCalculator = GeneralUtility::makeInstance(CacheHashCalculator::class);
1336 $cHashParameters = $cacheHashCalculator->getRelevantParameters($queryString);
1337 if (count($cHashParameters) > 1) {
1338 $this->useCacheHash = (
1339 $GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'disableNoCacheParameter'] ||
1340 !isset($parameters[
'no_cache']) ||
1341 !$parameters[
'no_cache']
1360 $includePage =
true;
1361 foreach (
$GLOBALS[
'TYPO3_CONF_VARS'][
'SC_OPTIONS'][
'cms/tslib/class.tslib_menu.php'][
'filterMenuPages'] ?? [] as $className) {
1362 $hookObject = GeneralUtility::makeInstance($className);
1363 if (!$hookObject instanceof AbstractMenuFilterPagesHookInterface) {
1364 throw new \UnexpectedValueException($className .
' must implement interface ' . AbstractMenuFilterPagesHookInterface::class, 1269877402);
1366 $includePage = $includePage && $hookObject->processFilter($data, $banUidArray, $spacer, $this);
1368 if (!$includePage) {
1371 if ($data[
'_SAFE']) {
1376 ($this->mconf[
'SPC'] || !$spacer)
1377 && (!$data[
'nav_hide'] || $this->conf[
'includeNotInMenu'])
1378 && !GeneralUtility::inList($this->doktypeExcludeList, $data[
'doktype'])
1379 && !in_array($data[
'uid'], $banUidArray,
false)
1382 if ($this->sys_page->isPageSuitableForLanguage($data, $this->getCurrentLanguageAspect())) {
1385 if ($this->conf[
'protectLvar'] ===
'all' || GeneralUtility::hideIfNotTranslated($data[
'l18n_cfg'])) {
1387 if (empty($olRec)) {
1390 $data[
'_ADD_GETVARS'] .=
'&L=0';
1416 if (!is_array($this->mconf[
'NO.']) && $this->mconf[
'NO']) {
1418 $this->mconf[
'NO.'] = [];
1420 $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
1421 $NOconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'NO.'], $splitCount);
1424 if ($this->mconf[
'RO']) {
1425 $ROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'RO.'], $splitCount);
1429 if (!empty($this->mconf[
'IFSUB'])) {
1431 $IFSUBROconf =
null;
1432 foreach ($NOconf as $key => $val) {
1435 if ($IFSUBconf ===
null) {
1436 $IFSUBconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'IFSUB.'], $splitCount);
1437 if (!empty($this->mconf[
'IFSUBRO'])) {
1438 $IFSUBROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'IFSUBRO.'], $splitCount);
1442 if (isset($IFSUBconf[$key])) {
1443 $NOconf[$key] = $IFSUBconf[$key];
1448 $ROconf[$key] = !empty($IFSUBROconf[$key]) ? $IFSUBROconf[$key] : $IFSUBconf[$key];
1454 if (!empty($this->mconf[
'ACT'])) {
1458 foreach ($NOconf as $key => $val) {
1461 if ($ACTconf ===
null) {
1462 $ACTconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'ACT.'], $splitCount);
1464 if (!empty($this->mconf[
'ACTRO'])) {
1465 $ACTROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'ACTRO.'], $splitCount);
1469 if (isset($ACTconf[$key])) {
1470 $NOconf[$key] = $ACTconf[$key];
1475 $ROconf[$key] = !empty($ACTROconf[$key]) ? $ACTROconf[$key] : $ACTconf[$key];
1482 if (!empty($this->mconf[
'ACTIFSUB'])) {
1483 $ACTIFSUBconf =
null;
1484 $ACTIFSUBROconf =
null;
1486 foreach ($NOconf as $key => $val) {
1489 if ($ACTIFSUBconf ===
null) {
1490 $ACTIFSUBconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'ACTIFSUB.'], $splitCount);
1492 if (!empty($this->mconf[
'ACTIFSUBRO'])) {
1493 $ACTIFSUBROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'ACTIFSUBRO.'], $splitCount);
1497 if (isset($ACTIFSUBconf[$key])) {
1498 $NOconf[$key] = $ACTIFSUBconf[$key];
1503 $ROconf[$key] = !empty($ACTIFSUBROconf[$key]) ? $ACTIFSUBROconf[$key] : $ACTIFSUBconf[$key];
1510 if (!empty($this->mconf[
'CUR'])) {
1513 foreach ($NOconf as $key => $val) {
1518 if ($CURconf ===
null) {
1519 $CURconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'CUR.'], $splitCount);
1520 if (!empty($this->mconf[
'CURRO'])) {
1521 $CURROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'CURRO.'], $splitCount);
1525 if (isset($CURconf[$key])) {
1526 $NOconf[$key] = $CURconf[$key];
1531 $ROconf[$key] = !empty($CURROconf[$key]) ? $CURROconf[$key] : $CURconf[$key];
1538 if (!empty($this->mconf[
'CURIFSUB'])) {
1539 $CURIFSUBconf =
null;
1540 $CURIFSUBROconf =
null;
1541 foreach ($NOconf as $key => $val) {
1544 if ($CURIFSUBconf ===
null) {
1545 $CURIFSUBconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'CURIFSUB.'], $splitCount);
1547 if (!empty($this->mconf[
'CURIFSUBRO'])) {
1548 $CURIFSUBROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'CURIFSUBRO.'], $splitCount);
1552 if ($CURIFSUBconf[$key]) {
1553 $NOconf[$key] = $CURIFSUBconf[$key];
1558 $ROconf[$key] = !empty($CURIFSUBROconf[$key]) ? $CURIFSUBROconf[$key] : $CURIFSUBconf[$key];
1564 if (!empty($this->mconf[
'USR'])) {
1568 foreach ($NOconf as $key => $val) {
1571 if ($USRconf ===
null) {
1572 $USRconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'USR.'], $splitCount);
1574 if (!empty($this->mconf[
'USRRO'])) {
1575 $USRROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'USRRO.'], $splitCount);
1579 if ($USRconf[$key]) {
1580 $NOconf[$key] = $USRconf[$key];
1585 $ROconf[$key] = !empty($USRROconf[$key]) ? $USRROconf[$key] : $USRconf[$key];
1591 if (!empty($this->mconf[
'SPC'])) {
1594 foreach ($NOconf as $key => $val) {
1597 if ($SPCconf ===
null) {
1598 $SPCconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'SPC.'], $splitCount);
1601 if (isset($SPCconf[$key])) {
1602 $NOconf[$key] = $SPCconf[$key];
1608 if (!empty($this->mconf[
'USERDEF1'])) {
1609 $USERDEF1conf =
null;
1610 $USERDEF1ROconf =
null;
1612 foreach ($NOconf as $key => $val) {
1615 if ($USERDEF1conf ===
null) {
1616 $USERDEF1conf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'USERDEF1.'], $splitCount);
1618 if (!empty($this->mconf[
'USERDEF1RO'])) {
1619 $USERDEF1ROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'USERDEF1RO.'], $splitCount);
1623 if (isset($USERDEF1conf[$key])) {
1624 $NOconf[$key] = $USERDEF1conf[$key];
1629 $ROconf[$key] = !empty($USERDEF1ROconf[$key]) ? $USERDEF1ROconf[$key] : $USERDEF1conf[$key];
1635 if (!empty($this->mconf[
'USERDEF2'])) {
1636 $USERDEF2conf =
null;
1637 $USERDEF2ROconf =
null;
1639 foreach ($NOconf as $key => $val) {
1642 if ($USERDEF2conf ===
null) {
1643 $USERDEF2conf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'USERDEF2.'], $splitCount);
1645 if (!empty($this->mconf[
'USERDEF2RO'])) {
1646 $USERDEF2ROconf = $typoScriptService->explodeConfigurationForOptionSplit((array)$this->mconf[
'USERDEF2RO.'], $splitCount);
1650 if (isset($USERDEF2conf[$key])) {
1651 $NOconf[$key] = $USERDEF2conf[$key];
1656 $ROconf[$key] = !empty($USERDEF2ROconf[$key]) ? $USERDEF2ROconf[$key] : $USERDEF2conf[$key];
1661 return [$NOconf, $ROconf];
1673 protected function link($key, $altTarget =
'', $typeOverride =
'')
1677 $cacheId =
'menu-generated-links-' . md5($key . $altTarget . $typeOverride . $MP_var . serialize($this->menuArr[$key]));
1678 $runtimeCachedLink = $runtimeCache->get($cacheId);
1679 if ($runtimeCachedLink !==
false) {
1680 return $runtimeCachedLink;
1684 $MP_params = $MP_var ?
'&MP=' . rawurlencode($MP_var) :
'';
1686 if ($this->mconf[
'overrideId'] || $this->menuArr[$key][
'overrideId']) {
1687 $overrideArray = [];
1689 $overrideArray[
'uid'] = $this->mconf[
'overrideId'] ?: $this->menuArr[$key][
'overrideId'];
1690 $overrideArray[
'alias'] =
'';
1694 $overrideArray =
'';
1698 $mainTarget = $altTarget;
1699 } elseif ($this->mconf[
'target.']) {
1700 $mainTarget = $this->parent_cObj->stdWrap($this->mconf[
'target'], $this->mconf[
'target.']);
1702 $mainTarget = $this->mconf[
'target'];
1705 $addParams = $this->mconf[
'addParams'] . $MP_params;
1706 if ($this->mconf[
'collapse'] && $this->
isActive($this->menuArr[$key][
'uid'], $this->
getMPvar($key))) {
1707 $thePage = $this->sys_page->getPage($this->menuArr[$key][
'pid']);
1708 $addParams .= $this->menuArr[$key][
'_ADD_GETVARS'];
1709 $LD = $this->
menuTypoLink($thePage, $mainTarget,
'',
'', $overrideArray, $addParams, $typeOverride);
1711 $addParams .= $this->I[
'val'][
'additionalParams'] . $this->menuArr[$key][
'_ADD_GETVARS'];
1712 $LD = $this->
menuTypoLink($this->menuArr[$key], $mainTarget,
'',
'', $overrideArray, $addParams, $typeOverride);
1715 if ($this->menuArr[$key][
'target']) {
1716 $LD[
'target'] = $this->menuArr[$key][
'target'];
1722 $LD[
'totalURL'] = $this->parent_cObj->typoLink_URL([
'parameter' => $externalUrl]);
1724 if (stripos($externalUrl,
'mailto:') === 0) {
1737 $menuItem = $this->menuArr[$key];
1739 $shortcut = $tsfe->sys_page->getPageShortcut(
1740 $menuItem[
'shortcut'],
1741 $menuItem[
'shortcut_mode'],
1747 }
catch (\Exception $ex) {
1749 if (!is_array($shortcut)) {
1750 $runtimeCache->set($cacheId, []);
1754 $LD[
'totalURL'] = $this->parent_cObj->typoLink_URL([
1755 'parameter' => $shortcut[
'uid'],
1756 'language' =>
'current',
1757 'additionalParams' => $addParams . $this->I[
'val'][
'additionalParams'] . $menuItem[
'_ADD_GETVARS'],
1758 'linkAccessRestrictedPages' => !empty($this->mconf[
'showAccessRestrictedPages'])
1762 $pageData = $shortcut;
1763 $pageData[
'_SHORTCUT_PAGE_UID'] = $this->menuArr[$key][
'uid'];
1765 $pageData = $this->menuArr[$key];
1770 if ($this->menuArr[$key][
'_OVERRIDE_HREF']) {
1771 $LD[
'totalURL'] = $this->menuArr[$key][
'_OVERRIDE_HREF'];
1772 if ($this->menuArr[$key][
'_OVERRIDE_TARGET']) {
1773 $LD[
'target'] = $this->menuArr[$key][
'_OVERRIDE_TARGET'];
1778 if ($this->mconf[
'JSWindow']) {
1779 $conf = $this->mconf[
'JSWindow.'];
1780 $url = $LD[
'totalURL'];
1781 $LD[
'totalURL'] =
'#';
1782 $onClick =
'openPic('
1783 . GeneralUtility::quoteJSvalue($tsfe->baseUrlWrap($url)) .
','
1784 .
'\'' . (
$conf[
'newWindow'] ? md5($url) :
'theNewPage') .
'\','
1785 . GeneralUtility::quoteJSvalue(
$conf[
'params']) .
'); return false;';
1786 $tsfe->setJS(
'openPic');
1796 if (preg_match(
'/([0-9]+[\\s])?(([0-9]+)x([0-9]+))?(:.+)?/s', $LD[
'target'], $matches) || $targetIsType) {
1798 if ((
int)$matches[1] || $targetIsType) {
1799 $LD[
'totalURL'] .= (strpos($LD[
'totalURL'],
'?') ===
false ?
'?' :
'&') .
'type=' . ($targetIsType ?: (
int)$matches[1]);
1800 $LD[
'target'] = $targetIsType ?
'' : trim(substr($LD[
'target'], strlen($matches[1]) + 1));
1803 if ($matches[3] && $matches[4]) {
1804 $JSparamWH =
'width=' . $matches[3] .
',height=' . $matches[4] . ($matches[5] ?
',' . substr($matches[5], 1) :
'');
1805 $onClick =
'openPic('
1806 . GeneralUtility::quoteJSvalue($tsfe->baseUrlWrap($LD[
'totalURL']))
1807 .
',\'FEopenLink\',' . GeneralUtility::quoteJSvalue($JSparamWH) .
');return false;';
1808 $tsfe->setJS(
'openPic');
1817 $list[
'HREF'] = (string)$LD[
'totalURL'] !==
'' ? $LD[
'totalURL'] : $tsfe->baseUrl;
1818 $list[
'TARGET'] = $LD[
'target'];
1819 $list[
'onClick'] = $onClick;
1820 $runtimeCache->set($cacheId, $list);
1838 && empty($page[
'shortcut'])
1839 && !empty($page[
'uid'])
1840 && !empty($page[
'_PAGES_OVERLAY'])
1841 && !empty($page[
'_PAGES_OVERLAY_UID'])
1844 $originalPage = $this->sys_page->getRawRecord(
'pages', $page[
'uid']);
1846 if ($originalPage[
'shortcut_mode'] === $page[
'shortcut_mode'] && !empty($originalPage[
'shortcut'])) {
1847 $page[
'shortcut'] = $originalPage[
'shortcut'];
1865 if ($this->mconf[
'showAccessRestrictedPages'] && $this->mconf[
'showAccessRestrictedPages'] !==
'NONE' && !$this->
getTypoScriptFrontendController()->checkPageGroupAccess($page)) {
1866 $thePage = $this->sys_page->getPage($this->mconf[
'showAccessRestrictedPages']);
1867 $addParams = str_replace(
1873 rawurlencode($LD[
'totalURL']),
1874 $page[
'_SHORTCUT_PAGE_UID'] ?? $page[
'uid']
1876 $this->mconf[
'showAccessRestrictedPages.'][
'addParams']
1878 $LD = $this->
menuTypoLink($thePage, $mainTarget,
'',
'',
'', $addParams, $typeOverride);
1889 protected function subMenu($uid, $objSuffix =
'')
1893 if (is_array($this->menuArr[$this->I[
'key']][
'_SUB_MENU']) && !empty($this->menuArr[$this->I[
'key']][
'_SUB_MENU'])) {
1894 $altArray = $this->menuArr[$this->I[
'key']][
'_SUB_MENU'];
1897 $menuType = $this->conf[($this->menuNumber + 1) . $objSuffix];
1899 if (isset($this->mconf[
'expAll.'])) {
1900 $this->mconf[
'expAll'] = $this->parent_cObj->stdWrap($this->mconf[
'expAll'], $this->mconf[
'expAll.']);
1902 if (($this->mconf[
'expAll'] || $this->
isNext($uid, $this->
getMPvar($this->I[
'key'])) || is_array($altArray)) && !$this->mconf[
'sectionIndex']) {
1904 $menuObjectFactory = GeneralUtility::makeInstance(MenuContentObjectFactory::class);
1906 $submenu = $menuObjectFactory->getMenuObjectByType($menuType);
1907 $submenu->entryLevel = $this->entryLevel + 1;
1910 if ($this->menuArr[$this->I[
'key']][
'_MP_PARAM']) {
1911 $submenu->MP_array[] = $this->menuArr[$this->I[
'key']][
'_MP_PARAM'];
1915 $submenu->setParentMenu($this->menuArr, $this->I[
'key']);
1917 if (is_array($altArray)) {
1918 $submenu->alternativeMenuTempArray = $altArray;
1920 if ($submenu->start($this->tmpl, $this->sys_page, $uid, $this->conf, $this->menuNumber + 1, $objSuffix)) {
1921 $submenu->makeMenu();
1924 $tempCountMenuObj = $tsfe->register[
'count_MENUOBJ'];
1926 $tsfe->register[
'count_MENUOBJ'] = 0;
1927 $content = $submenu->writeMenu();
1929 $tsfe->register[
'count_MENUOBJ'] = $tempCountMenuObj;
1930 $tsfe->register[
'count_menuItems'] = count($this->menuArr);
1933 }
catch (
Exception\NoSuchMenuTypeException $e) {
1947 protected function isNext($uid, $MPvar =
'')
1950 if (!empty($this->alwaysActivePIDlist) && in_array((
int)$uid, $this->alwaysActivePIDlist,
true)) {
1953 $testUid = $uid . ($MPvar ?
':' . $MPvar :
'');
1954 if ($uid && $testUid == $this->nextActive) {
1967 protected function isActive($uid, $MPvar =
'')
1970 if (!empty($this->alwaysActivePIDlist) && in_array((
int)$uid, $this->alwaysActivePIDlist,
true)) {
1973 $testUid = $uid . ($MPvar ?
':' . $MPvar :
'');
1974 if ($uid && in_array(
'ITEM:' . $testUid, $this->rL_uidRegister,
true)) {
1987 protected function isCurrent($uid, $MPvar =
'')
1989 $testUid = $uid . ($MPvar ?
':' . $MPvar :
'');
1990 return $uid && end($this->rL_uidRegister) ===
'ITEM:' . $testUid;
2002 $cacheId =
'menucontentobject-is-submenu-decision-' . $uid;
2004 $cachedDecision = $runtimeCache->get($cacheId);
2005 if (isset($cachedDecision[
'result'])) {
2006 return $cachedDecision[
'result'];
2010 $mount_info = $this->sys_page->getMountPointInfo($uid);
2011 if (is_array($mount_info)) {
2012 $uid = $mount_info[
'mount_pid'];
2014 $recs = $this->sys_page->getMenu($uid,
'uid,pid,doktype,mount_pid,mount_pid_ol,nav_hide,shortcut,shortcut_mode,l18n_cfg');
2015 $hasSubPages =
false;
2018 foreach ($recs as $theRec) {
2020 if (GeneralUtility::inList($this->doktypeExcludeList, $theRec[
'doktype'] ??
'')) {
2025 if (isset($theRec[
'nav_hide']) && $theRec[
'nav_hide']
2026 && (!isset($this->conf[
'includeNotInMenu']) || !$this->conf[
'includeNotInMenu'])
2032 if (!$languageId && GeneralUtility::hideIfDefaultLanguage($theRec[
'l18n_cfg'] ?? 0)) {
2037 $hideIfNotTranslated = GeneralUtility::hideIfNotTranslated($theRec[
'l18n_cfg'] ??
null);
2038 if ($languageId && $hideIfNotTranslated && !$theRec[
'_PAGES_OVERLAY']) {
2042 if (in_array($theRec[
'uid'], $bannedUids)) {
2045 $hasSubPages =
true;
2048 $runtimeCache->set($cacheId, [
'result' => $hasSubPages]);
2049 return $hasSubPages;
2064 if ($this->menuArr[$key][
'ITEM_STATE'] ??
false) {
2065 if ((
string)$this->menuArr[$key][
'ITEM_STATE'] === (
string)$kind) {
2071 $natVal = (bool)$this->menuArr[$key][
'isSpacer'];
2074 $natVal = $this->
isSubMenu($this->menuArr[$key][
'uid']);
2089 $natVal = (bool)$this->menuArr[$key][
'fe_group'];
2107 $title = trim(strip_tags($title));
2108 $titleLen = strlen($title);
2109 for ($a = 0; $a < $titleLen; $a++) {
2110 $key = strtoupper(substr($title, $a, 1));
2111 if (preg_match(
'/[A-Z]/', $key) && !isset($tsfe->accessKey[$key])) {
2112 $tsfe->accessKey[$key] = 1;
2113 $result[
'code'] =
' accesskey="' . $key .
'"';
2114 $result[
'alt'] =
' (ALT+' . $key .
')';
2132 if ($this->mconf[$mConfKey]) {
2133 $funcConf = $this->mconf[$mConfKey .
'.'];
2134 $funcConf[
'parentObj'] = $this;
2135 $passVar = $this->parent_cObj->callUserFunction($this->mconf[$mConfKey], $funcConf, $passVar);
2145 $params = trim($this->I[
'val'][
'ATagParams']) . $this->I[
'accessKey'][
'code'];
2146 $params = $params !==
'' ?
' ' . $params :
'';
2147 $this->I[
'A1'] =
'<a ' . GeneralUtility::implodeAttributes($this->I[
'linkHREF'],
true) . $params .
'>';
2148 $this->I[
'A2'] =
'</a>';
2160 return trim($nav_title) !==
'' ? $nav_title : $title;
2172 if (
$GLOBALS[
'TYPO3_CONF_VARS'][
'FE'][
'enable_mount_pids']) {
2175 if ($this->menuArr[$key][
'_MP_PARAM']) {
2176 $localMP_array[] = $this->menuArr[$key][
'_MP_PARAM'];
2178 return !empty($localMP_array) ? implode(
',', $localMP_array) :
'';
2190 return $this->doktypeExcludeList ?
' AND pages.doktype NOT IN (' . $this->doktypeExcludeList .
')' :
'';
2200 $excludeUidList = isset($this->conf[
'excludeUidList.'])
2201 ? $this->parent_cObj->stdWrap($this->conf[
'excludeUidList'], $this->conf[
'excludeUidList.'])
2202 : $this->conf[
'excludeUidList'];
2204 if (!trim($excludeUidList)) {
2209 return GeneralUtility::intExplode(
',', $banUidList);
2224 protected function menuTypoLink($page, $oTarget, $no_cache, $script, $overrideArray =
'', $addParams =
'', $typeOverride =
'')
2227 'parameter' => is_array($overrideArray) && $overrideArray[
'uid'] ? $overrideArray[
'uid'] : $page[
'uid']
2230 $conf[
'parameter'] .=
',' . (int)$typeOverride;
2233 $conf[
'additionalParams'] = $addParams;
2239 if ($page[
'_PAGES_OVERLAY_REQUESTEDLANGUAGE'] ?? 0) {
2240 $conf[
'language'] = $page[
'_PAGES_OVERLAY_REQUESTEDLANGUAGE'];
2243 $conf[
'no_cache'] =
true;
2244 } elseif ($this->useCacheHash) {
2245 $conf[
'useCacheHash'] =
true;
2248 $conf[
'target'] = $oTarget;
2250 if ($page[
'sectionIndex_uid'] ??
false) {
2251 $conf[
'section'] = $page[
'sectionIndex_uid'];
2253 $conf[
'linkAccessRestrictedPages'] = !empty($this->mconf[
'showAccessRestrictedPages']);
2254 $this->parent_cObj->typoLink(
'|',
$conf);
2255 $LD = $this->parent_cObj->lastTypoLinkLD;
2256 $LD[
'totalURL'] = $this->parent_cObj->lastTypoLinkUrl;
2271 protected function sectionIndex($altSortField, $pid =
null)
2273 $pid = (int)($pid ?: $this->
id);
2274 $basePageRow = $this->sys_page->getPage($pid);
2275 if (!is_array($basePageRow)) {
2279 $configuration = $this->mconf[
'sectionIndex.'] ?? [];
2281 if (trim($configuration[
'useColPos'] ??
'') !==
''
2282 || (isset($configuration[
'useColPos.']) && is_array($configuration[
'useColPos.']))
2284 $useColPos = $tsfe->cObj->stdWrap($configuration[
'useColPos'] ??
'', $configuration[
'useColPos.'] ?? []);
2285 $useColPos = (int)$useColPos;
2288 'pidInList' => $pid,
2289 'orderBy' => $altSortField,
2290 'languageField' =>
'sys_language_uid',
2294 if ($useColPos >= 0) {
2295 $expressionBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
2296 ->getConnectionForTable(
'tt_content')
2297 ->getExpressionBuilder();
2298 $selectSetup[
'where'] = $expressionBuilder->eq(
'colPos', $useColPos);
2301 if ($basePageRow[
'content_from_pid'] ??
false) {
2304 $selectSetup[
'pidInList'] = $basePageRow[
'content_from_pid'];
2306 $statement = $this->parent_cObj->exec_getQuery(
'tt_content', $selectSetup);
2308 $message =
'SectionIndex: Query to fetch the content elements failed!';
2309 throw new \UnexpectedValueException($message, 1337334849);
2312 while ($row = $statement->fetch()) {
2313 $this->sys_page->versionOL(
'tt_content', $row);
2315 $row = $this->sys_page->getRecordOverlay(
2318 $basePageRow[
'_PAGES_OVERLAY_LANGUAGE'],
2322 if ($this->mconf[
'sectionIndex.'][
'type'] !==
'all') {
2323 $doIncludeInSectionIndex = $row[
'sectionIndex'] >= 1;
2324 $doHeaderCheck = $this->mconf[
'sectionIndex.'][
'type'] ===
'header';
2325 $isValidHeader = ((int)$row[
'header_layout'] !== 100 || !empty($this->mconf[
'sectionIndex.'][
'includeHiddenHeaders'])) && trim($row[
'header']) !==
'';
2326 if (!$doIncludeInSectionIndex || $doHeaderCheck && !$isValidHeader) {
2330 if (is_array($row)) {
2331 $uid = $row[
'uid'] ??
null;
2333 $result[$uid][
'title'] = $row[
'header'];
2334 $result[$uid][
'nav_title'] = $row[
'header'];
2337 $result[$uid][
'subtitle'] = $row[
'subheader'] ??
'';
2338 $result[$uid][
'starttime'] = $row[
'starttime'] ??
'';
2340 $result[$uid][
'fe_group'] = $row[
'fe_group'] ??
'';
2341 $result[$uid][
'media'] = $row[
'media'] ??
'';
2342 $result[$uid][
'header_layout'] = $row[
'header_layout'] ??
'';
2343 $result[$uid][
'bodytext'] = $row[
'bodytext'] ??
'';
2345 $result[$uid][
'sectionIndex_uid'] = $uid;
2382 return GeneralUtility::makeInstance(Context::class)->getAspect(
'language');
2390 return GeneralUtility::makeInstance(TimeTracker::class);
2398 return GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_hash');
2406 return GeneralUtility::makeInstance(CacheManager::class)->getCache(
'cache_runtime');
2417 $matcher = GeneralUtility::makeInstance(SiteMatcher::class);
2433 && (is_int($menuItemKey) && $menuItemKey >= 0 && isset(
$menuArr[$menuItemKey]))
2436 $this->parentMenuArrItemKey = $menuItemKey;
2448 $this->menuNumber > 1
2449 && is_array($this->parentMenuArr)
2450 && !empty($this->parentMenuArr)