/**
  * @test
  */
 public function getTreeListReturnsChildPageUidsAndOriginalPidForNegativeValue()
 {
     $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
     $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getRawRecord')->will($this->onConsecutiveCalls(array('uid' => 17), array('uid' => 321), array('uid' => 719), array('uid' => 42)));
     $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
     $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetRows')->will($this->onConsecutiveCalls(array(array('uid' => 321)), array(array('uid' => 719)), array(array('uid' => 42))));
     // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
     // 17 is negative, we expect 17 to be included in result
     $result = $this->subject->getTreeList(-17, 5, 0, true);
     $expectedResult = '42,719,321,17';
     $this->assertEquals($expectedResult, $result);
 }
Exemplo n.º 2
0
 /**
  * Returns a commalist of page ids for a query (eg. 'WHERE pid IN (...)')
  *
  * @param string $pid_list A comma list of page ids (if empty current page is used)
  * @param int $recursive An integer >=0 telling how deep to dig for pids under each entry in $pid_list
  * @return string List of PID values (comma separated)
  */
 public function pi_getPidList($pid_list, $recursive = 0)
 {
     if (!strcmp($pid_list, '')) {
         $pid_list = $this->frontendController->id;
     }
     $recursive = MathUtility::forceIntegerInRange($recursive, 0);
     $pid_list_arr = array_unique(GeneralUtility::trimExplode(',', $pid_list, TRUE));
     $pid_list = array();
     foreach ($pid_list_arr as $val) {
         $val = MathUtility::forceIntegerInRange($val, 0);
         if ($val) {
             $_list = $this->cObj->getTreeList(-1 * $val, $recursive);
             if ($_list) {
                 $pid_list[] = $_list;
             }
         }
     }
     return implode(',', $pid_list);
 }
Exemplo n.º 3
0
 /**
  * Returns a commalist of page ids for a query (eg. 'WHERE pid IN (...)')
  *
  * @param string $pid_list A comma list of page ids (if empty current page is used)
  * @param integer$recursive An integer >=0 telling how deep to dig for pids under each entry in $pid_list
  * @return string List of PID values (comma separated)
  * @todo Define visibility
  */
 public function pi_getPidList($pid_list, $recursive = 0)
 {
     if (!strcmp($pid_list, '')) {
         $pid_list = $GLOBALS['TSFE']->id;
     }
     $recursive = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($recursive, 0);
     $pid_list_arr = array_unique(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $pid_list, 1));
     $pid_list = array();
     foreach ($pid_list_arr as $val) {
         $val = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($val, 0);
         if ($val) {
             $_list = $this->cObj->getTreeList(-1 * $val, $recursive);
             if ($_list) {
                 $pid_list[] = $_list;
             }
         }
     }
     return implode(',', $pid_list);
 }
 /**
  * Creates the menu in the internal variables, ready for output.
  * Basically this will read the page records needed and fill in the internal $this->menuArr
  * Based on a hash of this array and some other variables the $this->result variable will be loaded either from cache OR by calling the generate() method of the class to create the menu for real.
  *
  * @return void
  * @todo Define visibility
  */
 public function makeMenu()
 {
     if ($this->id) {
         $this->useCacheHash = FALSE;
         // Initializing showAccessRestrictedPages
         if ($this->mconf['showAccessRestrictedPages']) {
             // SAVING where_groupAccess
             $SAVED_where_groupAccess = $this->sys_page->where_groupAccess;
             // Temporarily removing fe_group checking!
             $this->sys_page->where_groupAccess = '';
         }
         // Begin production of menu:
         $temp = array();
         $altSortFieldValue = trim($this->mconf['alternativeSortingField']);
         $altSortField = $altSortFieldValue ?: 'sorting';
         // ... only for the FIRST level of a HMENU
         if ($this->menuNumber == 1 && $this->conf['special']) {
             $value = isset($this->conf['special.']['value.']) ? $this->parent_cObj->stdWrap($this->conf['special.']['value'], $this->conf['special.']['value.']) : $this->conf['special.']['value'];
             switch ($this->conf['special']) {
                 case 'userfunction':
                     $temp = $this->parent_cObj->callUserFunction($this->conf['special.']['userFunc'], array_merge($this->conf['special.'], array('_altSortField' => $altSortField)), '');
                     if (!is_array($temp)) {
                         $temp = array();
                     }
                     break;
                 case 'language':
                     $temp = array();
                     // Getting current page record NOT overlaid by any translation:
                     $currentPageWithNoOverlay = $this->sys_page->getRawRecord('pages', $GLOBALS['TSFE']->page['uid']);
                     // Traverse languages set up:
                     $languageItems = GeneralUtility::intExplode(',', $value);
                     foreach ($languageItems as $sUid) {
                         // Find overlay record:
                         if ($sUid) {
                             $lRecs = $this->sys_page->getPageOverlay($GLOBALS['TSFE']->page['uid'], $sUid);
                         } else {
                             $lRecs = array();
                         }
                         // Checking if the "disabled" state should be set.
                         if (GeneralUtility::hideIfNotTranslated($GLOBALS['TSFE']->page['l18n_cfg']) && $sUid && !count($lRecs) || $GLOBALS['TSFE']->page['l18n_cfg'] & 1 && (!$sUid || !count($lRecs)) || !$this->conf['special.']['normalWhenNoLanguage'] && $sUid && !count($lRecs)) {
                             $iState = $GLOBALS['TSFE']->sys_language_uid == $sUid ? 'USERDEF2' : 'USERDEF1';
                         } else {
                             $iState = $GLOBALS['TSFE']->sys_language_uid == $sUid ? 'ACT' : 'NO';
                         }
                         if ($this->conf['addQueryString']) {
                             $getVars = $this->parent_cObj->getQueryArguments($this->conf['addQueryString.'], array('L' => $sUid), TRUE);
                             $this->analyzeCacheHashRequirements($getVars);
                         } else {
                             $getVars = '&L=' . $sUid;
                         }
                         // Adding menu item:
                         $temp[] = array_merge(array_merge($currentPageWithNoOverlay, $lRecs), array('ITEM_STATE' => $iState, '_ADD_GETVARS' => $getVars, '_SAFE' => TRUE));
                     }
                     break;
                 case 'directory':
                     if ($value == '') {
                         $value = $GLOBALS['TSFE']->page['uid'];
                     }
                     $items = GeneralUtility::intExplode(',', $value);
                     foreach ($items as $id) {
                         $MP = $this->tmpl->getFromMPmap($id);
                         // Checking if a page is a mount page and if so, change the ID and set the MP var properly.
                         $mount_info = $this->sys_page->getMountPointInfo($id);
                         if (is_array($mount_info)) {
                             if ($mount_info['overlay']) {
                                 // Overlays should already have their full MPvars calculated:
                                 $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
                                 $MP = $MP ? $MP : $mount_info['MPvar'];
                             } else {
                                 $MP = ($MP ? $MP . ',' : '') . $mount_info['MPvar'];
                             }
                             $id = $mount_info['mount_pid'];
                         }
                         // Get sub-pages:
                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . (int) $id . $this->sys_page->where_hid_del, '', $altSortField);
                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                             $row = $this->sys_page->getPage($row['uid']);
                             $GLOBALS['TSFE']->sys_page->versionOL('pages', $row, TRUE);
                             if (!empty($row)) {
                                 // Keep mount point?
                                 $mount_info = $this->sys_page->getMountPointInfo($row['uid'], $row);
                                 // There is a valid mount point.
                                 if (is_array($mount_info) && $mount_info['overlay']) {
                                     // Using "getPage" is OK since we need the check for enableFields
                                     // AND for type 2 of mount pids we DO require a doktype < 200!
                                     $mp_row = $this->sys_page->getPage($mount_info['mount_pid']);
                                     if (count($mp_row)) {
                                         $row = $mp_row;
                                         $row['_MP_PARAM'] = $mount_info['MPvar'];
                                     } else {
                                         // If the mount point could not be fetched with respect
                                         // to enableFields, unset the row so it does not become a part of the menu!
                                         unset($row);
                                     }
                                 }
                                 // Add external MP params, then the row:
                                 if (!empty($row)) {
                                     if ($MP) {
                                         $row['_MP_PARAM'] = $MP . ($row['_MP_PARAM'] ? ',' . $row['_MP_PARAM'] : '');
                                     }
                                     $temp[$row['uid']] = $row;
                                 }
                             }
                         }
                         $GLOBALS['TYPO3_DB']->sql_free_result($res);
                     }
                     break;
                 case 'list':
                     if ($value == '') {
                         $value = $this->id;
                     }
                     $skippedEnableFields = array();
                     if (!empty($this->mconf['showAccessRestrictedPages'])) {
                         $skippedEnableFields = array('fe_group' => 1);
                     }
                     /** @var \TYPO3\CMS\Core\Database\RelationHandler $loadDB*/
                     $loadDB = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\RelationHandler');
                     $loadDB->setFetchAllFields(TRUE);
                     $loadDB->start($value, 'pages');
                     $loadDB->additionalWhere['pages'] = $this->parent_cObj->enableFields('pages', FALSE, $skippedEnableFields);
                     $loadDB->getFromDB();
                     foreach ($loadDB->itemArray as $val) {
                         $MP = $this->tmpl->getFromMPmap($val['id']);
                         // Keep mount point?
                         $mount_info = $this->sys_page->getMountPointInfo($val['id']);
                         // There is a valid mount point.
                         if (is_array($mount_info) && $mount_info['overlay']) {
                             // Using "getPage" is OK since we need the check for enableFields
                             // AND for type 2 of mount pids we DO require a doktype < 200!
                             $mp_row = $this->sys_page->getPage($mount_info['mount_pid']);
                             if (count($mp_row)) {
                                 $row = $mp_row;
                                 $row['_MP_PARAM'] = $mount_info['MPvar'];
                                 // Overlays should already have their full MPvars calculated
                                 if ($mount_info['overlay']) {
                                     $MP = $this->tmpl->getFromMPmap($mount_info['mount_pid']);
                                     if ($MP) {
                                         unset($row['_MP_PARAM']);
                                     }
                                 }
                             } else {
                                 // If the mount point could not be fetched with respect to
                                 // enableFields, unset the row so it does not become a part of the menu!
                                 unset($row);
                             }
                         } else {
                             $row = $loadDB->results['pages'][$val['id']];
                         }
                         //Add versioning overlay for current page (to respect workspaces)
                         if (is_array($row)) {
                             $this->sys_page->versionOL('pages', $row, TRUE);
                         }
                         // Add external MP params, then the row:
                         if (is_array($row)) {
                             if ($MP) {
                                 $row['_MP_PARAM'] = $MP . ($row['_MP_PARAM'] ? ',' . $row['_MP_PARAM'] : '');
                             }
                             $temp[] = $this->sys_page->getPageOverlay($row);
                         }
                     }
                     break;
                 case 'updated':
                     if ($value == '') {
                         $value = $GLOBALS['TSFE']->page['uid'];
                     }
                     $items = GeneralUtility::intExplode(',', $value);
                     if (MathUtility::canBeInterpretedAsInteger($this->conf['special.']['depth'])) {
                         $depth = MathUtility::forceIntegerInRange($this->conf['special.']['depth'], 1, 20);
                     } else {
                         $depth = 20;
                     }
                     // Max number of items
                     $limit = MathUtility::forceIntegerInRange($this->conf['special.']['limit'], 0, 100);
                     $maxAge = (int) $this->parent_cObj->calc($this->conf['special.']['maxAge']);
                     if (!$limit) {
                         $limit = 10;
                     }
                     // *'auto', 'manual', 'tstamp'
                     $mode = $this->conf['special.']['mode'];
                     // Get id's
                     $id_list_arr = array();
                     foreach ($items as $id) {
                         $bA = MathUtility::forceIntegerInRange($this->conf['special.']['beginAtLevel'], 0, 100);
                         $id_list_arr[] = $this->parent_cObj->getTreeList(-1 * $id, $depth - 1 + $bA, $bA - 1);
                     }
                     $id_list = implode(',', $id_list_arr);
                     // Get sortField (mode)
                     switch ($mode) {
                         case 'starttime':
                             $sortField = 'starttime';
                             break;
                         case 'lastUpdated':
                         case 'manual':
                             $sortField = 'lastUpdated';
                             break;
                         case 'tstamp':
                             $sortField = 'tstamp';
                             break;
                         case 'crdate':
                             $sortField = 'crdate';
                             break;
                         default:
                             $sortField = 'SYS_LASTCHANGED';
                     }
                     // Get
                     $extraWhere = ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0') . $this->getDoktypeExcludeWhere();
                     if ($this->conf['special.']['excludeNoSearchPages']) {
                         $extraWhere .= ' AND pages.no_search=0';
                     }
                     if ($maxAge > 0) {
                         $extraWhere .= ' AND ' . $sortField . '>' . ($GLOBALS['SIM_ACCESS_TIME'] - $maxAge);
                     }
                     $res = $this->parent_cObj->exec_getQuery('pages', array('pidInList' => '0', 'uidInList' => $id_list, 'where' => $sortField . '>=0' . $extraWhere, 'orderBy' => $altSortFieldValue ? $altSortFieldValue : $sortField . ' desc', 'max' => $limit));
                     while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                         $GLOBALS['TSFE']->sys_page->versionOL('pages', $row, TRUE);
                         if (is_array($row)) {
                             $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
                         }
                     }
                     break;
                 case 'keywords':
                     list($value) = GeneralUtility::intExplode(',', $value);
                     if (!$value) {
                         $value = $GLOBALS['TSFE']->page['uid'];
                     }
                     if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) {
                         $kw = isset($this->conf['special.']['setKeywords.']) ? $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']) : $this->conf['special.']['setKeywords'];
                     } else {
                         // The page record of the 'value'.
                         $value_rec = $this->sys_page->getPage($value);
                         $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords';
                         // keywords.
                         $kw = trim($this->parent_cObj->keywords($value_rec[$kfieldSrc]));
                     }
                     // *'auto', 'manual', 'tstamp'
                     $mode = $this->conf['special.']['mode'];
                     switch ($mode) {
                         case 'starttime':
                             $sortField = 'starttime';
                             break;
                         case 'lastUpdated':
                         case 'manual':
                             $sortField = 'lastUpdated';
                             break;
                         case 'tstamp':
                             $sortField = 'tstamp';
                             break;
                         case 'crdate':
                             $sortField = 'crdate';
                             break;
                         default:
                             $sortField = 'SYS_LASTCHANGED';
                     }
                     // Depth, limit, extra where
                     if (MathUtility::canBeInterpretedAsInteger($this->conf['special.']['depth'])) {
                         $depth = MathUtility::forceIntegerInRange($this->conf['special.']['depth'], 0, 20);
                     } else {
                         $depth = 20;
                     }
                     // Max number of items
                     $limit = MathUtility::forceIntegerInRange($this->conf['special.']['limit'], 0, 100);
                     $extraWhere = ' AND pages.uid<>' . $value . ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0') . $this->getDoktypeExcludeWhere();
                     if ($this->conf['special.']['excludeNoSearchPages']) {
                         $extraWhere .= ' AND pages.no_search=0';
                     }
                     // Start point
                     $eLevel = $this->parent_cObj->getKey(isset($this->conf['special.']['entryLevel.']) ? $this->parent_cObj->stdWrap($this->conf['special.']['entryLevel'], $this->conf['special.']['entryLevel.']) : $this->conf['special.']['entryLevel'], $this->tmpl->rootLine);
                     $startUid = (int) $this->tmpl->rootLine[$eLevel]['uid'];
                     // Which field is for keywords
                     $kfield = 'keywords';
                     if ($this->conf['special.']['keywordsField']) {
                         list($kfield) = explode(' ', trim($this->conf['special.']['keywordsField']));
                     }
                     // If there are keywords and the startuid is present.
                     if ($kw && $startUid) {
                         $bA = MathUtility::forceIntegerInRange($this->conf['special.']['beginAtLevel'], 0, 100);
                         $id_list = $this->parent_cObj->getTreeList(-1 * $startUid, $depth - 1 + $bA, $bA - 1);
                         $kwArr = explode(',', $kw);
                         foreach ($kwArr as $word) {
                             $word = trim($word);
                             if ($word) {
                                 $keyWordsWhereArr[] = $kfield . ' LIKE \'%' . $GLOBALS['TYPO3_DB']->quoteStr($word, 'pages') . '%\'';
                             }
                         }
                         $res = $this->parent_cObj->exec_getQuery('pages', array('pidInList' => '0', 'uidInList' => $id_list, 'where' => '(' . implode(' OR ', $keyWordsWhereArr) . ')' . $extraWhere, 'orderBy' => $altSortFieldValue ? $altSortFieldValue : $sortField . ' desc', 'max' => $limit));
                         while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
                             $GLOBALS['TSFE']->sys_page->versionOL('pages', $row, TRUE);
                             if (is_array($row)) {
                                 $temp[$row['uid']] = $this->sys_page->getPageOverlay($row);
                             }
                         }
                     }
                     break;
                 case 'categories':
                     /** @var \TYPO3\CMS\Frontend\ContentObject\Menu\CategoryMenuUtility $categoryMenuUtility */
                     $categoryMenuUtility = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\Menu\\CategoryMenuUtility');
                     $temp = $categoryMenuUtility->collectPages($value, $this->conf['special.'], $this);
                     break;
                 case 'rootline':
                     $range = isset($this->conf['special.']['range.']) ? $this->parent_cObj->stdWrap($this->conf['special.']['range'], $this->conf['special.']['range.']) : $this->conf['special.']['range'];
                     $begin_end = explode('|', $range);
                     $begin_end[0] = (int) $begin_end[0];
                     if (!MathUtility::canBeInterpretedAsInteger($begin_end[1])) {
                         $begin_end[1] = -1;
                     }
                     $beginKey = $this->parent_cObj->getKey($begin_end[0], $this->tmpl->rootLine);
                     $endKey = $this->parent_cObj->getKey($begin_end[1], $this->tmpl->rootLine);
                     if ($endKey < $beginKey) {
                         $endKey = $beginKey;
                     }
                     $rl_MParray = array();
                     foreach ($this->tmpl->rootLine as $k_rl => $v_rl) {
                         // For overlaid mount points, set the variable right now:
                         if ($v_rl['_MP_PARAM'] && $v_rl['_MOUNT_OL']) {
                             $rl_MParray[] = $v_rl['_MP_PARAM'];
                         }
                         // Traverse rootline:
                         if ($k_rl >= $beginKey && $k_rl <= $endKey) {
                             $temp_key = $k_rl;
                             $temp[$temp_key] = $this->sys_page->getPage($v_rl['uid']);
                             if (count($temp[$temp_key])) {
                                 // If there are no specific target for the page, put the level specific target on.
                                 if (!$temp[$temp_key]['target']) {
                                     $temp[$temp_key]['target'] = $this->conf['special.']['targets.'][$k_rl];
                                     $temp[$temp_key]['_MP_PARAM'] = implode(',', $rl_MParray);
                                 }
                             } else {
                                 unset($temp[$temp_key]);
                             }
                         }
                         // For normal mount points, set the variable for next level.
                         if ($v_rl['_MP_PARAM'] && !$v_rl['_MOUNT_OL']) {
                             $rl_MParray[] = $v_rl['_MP_PARAM'];
                         }
                     }
                     // Reverse order of elements (e.g. "1,2,3,4" gets "4,3,2,1"):
                     if (isset($this->conf['special.']['reverseOrder']) && $this->conf['special.']['reverseOrder']) {
                         $temp = array_reverse($temp);
                         $rl_MParray = array_reverse($rl_MParray);
                     }
                     break;
                 case 'browse':
                     list($value) = GeneralUtility::intExplode(',', $value);
                     if (!$value) {
                         $value = $GLOBALS['TSFE']->page['uid'];
                     }
                     // Will not work out of rootline
                     if ($value != $this->tmpl->rootLine[0]['uid']) {
                         $recArr = array();
                         // The page record of the 'value'.
                         $value_rec = $this->sys_page->getPage($value);
                         // 'up' page cannot be outside rootline
                         if ($value_rec['pid']) {
                             // The page record of 'up'.
                             $recArr['up'] = $this->sys_page->getPage($value_rec['pid']);
                         }
                         // If the 'up' item was NOT level 0 in rootline...
                         if ($recArr['up']['pid'] && $value_rec['pid'] != $this->tmpl->rootLine[0]['uid']) {
                             // The page record of "index".
                             $recArr['index'] = $this->sys_page->getPage($recArr['up']['pid']);
                         }
                         // prev / next is found
                         $prevnext_menu = $this->removeInaccessiblePages($this->sys_page->getMenu($value_rec['pid'], '*', $altSortField));
                         $lastKey = 0;
                         $nextActive = 0;
                         foreach ($prevnext_menu as $k_b => $v_b) {
                             if ($nextActive) {
                                 $recArr['next'] = $v_b;
                                 $nextActive = 0;
                             }
                             if ($v_b['uid'] == $value) {
                                 if ($lastKey) {
                                     $recArr['prev'] = $prevnext_menu[$lastKey];
                                 }
                                 $nextActive = 1;
                             }
                             $lastKey = $k_b;
                         }
                         reset($prevnext_menu);
                         $recArr['first'] = pos($prevnext_menu);
                         end($prevnext_menu);
                         $recArr['last'] = pos($prevnext_menu);
                         // prevsection / nextsection is found
                         // You can only do this, if there is a valid page two levels up!
                         if (is_array($recArr['index'])) {
                             $prevnextsection_menu = $this->removeInaccessiblePages($this->sys_page->getMenu($recArr['index']['uid'], '*', $altSortField));
                             $lastKey = 0;
                             $nextActive = 0;
                             foreach ($prevnextsection_menu as $k_b => $v_b) {
                                 if ($nextActive) {
                                     $sectionRec_temp = $this->removeInaccessiblePages($this->sys_page->getMenu($v_b['uid'], '*', $altSortField));
                                     if (count($sectionRec_temp)) {
                                         reset($sectionRec_temp);
                                         $recArr['nextsection'] = pos($sectionRec_temp);
                                         end($sectionRec_temp);
                                         $recArr['nextsection_last'] = pos($sectionRec_temp);
                                         $nextActive = 0;
                                     }
                                 }
                                 if ($v_b['uid'] == $value_rec['pid']) {
                                     if ($lastKey) {
                                         $sectionRec_temp = $this->removeInaccessiblePages($this->sys_page->getMenu($prevnextsection_menu[$lastKey]['uid'], '*', $altSortField));
                                         if (count($sectionRec_temp)) {
                                             reset($sectionRec_temp);
                                             $recArr['prevsection'] = pos($sectionRec_temp);
                                             end($sectionRec_temp);
                                             $recArr['prevsection_last'] = pos($sectionRec_temp);
                                         }
                                     }
                                     $nextActive = 1;
                                 }
                                 $lastKey = $k_b;
                             }
                         }
                         if ($this->conf['special.']['items.']['prevnextToSection']) {
                             if (!is_array($recArr['prev']) && is_array($recArr['prevsection_last'])) {
                                 $recArr['prev'] = $recArr['prevsection_last'];
                             }
                             if (!is_array($recArr['next']) && is_array($recArr['nextsection'])) {
                                 $recArr['next'] = $recArr['nextsection'];
                             }
                         }
                         $items = explode('|', $this->conf['special.']['items']);
                         $c = 0;
                         foreach ($items as $k_b => $v_b) {
                             $v_b = strtolower(trim($v_b));
                             if ((int) $this->conf['special.'][$v_b . '.']['uid']) {
                                 $recArr[$v_b] = $this->sys_page->getPage((int) $this->conf['special.'][$v_b . '.']['uid']);
                             }
                             if (is_array($recArr[$v_b])) {
                                 $temp[$c] = $recArr[$v_b];
                                 if ($this->conf['special.'][$v_b . '.']['target']) {
                                     $temp[$c]['target'] = $this->conf['special.'][$v_b . '.']['target'];
                                 }
                                 $tmpSpecialFields = $this->conf['special.'][$v_b . '.']['fields.'];
                                 if (is_array($tmpSpecialFields)) {
                                     foreach ($tmpSpecialFields as $fk => $val) {
                                         $temp[$c][$fk] = $val;
                                     }
                                 }
                                 $c++;
                             }
                         }
                     }
                     break;
             }
             if ($this->mconf['sectionIndex']) {
                 $sectionIndexes = array();
                 foreach ($temp as $page) {
                     $sectionIndexes = $sectionIndexes + $this->sectionIndex($altSortField, $page['uid']);
                 }
                 $temp = $sectionIndexes;
             }
         } elseif (is_array($this->alternativeMenuTempArray)) {
             // Setting $temp array if not level 1.
             $temp = $this->alternativeMenuTempArray;
         } elseif ($this->mconf['sectionIndex']) {
             $temp = $this->sectionIndex($altSortField);
         } else {
             // Default:
             // gets the menu
             $temp = $this->sys_page->getMenu($this->id, '*', $altSortField);
         }
         $c = 0;
         $c_b = 0;
         $minItems = (int) ($this->mconf['minItems'] ?: $this->conf['minItems']);
         $maxItems = (int) ($this->mconf['maxItems'] ?: $this->conf['maxItems']);
         $begin = $this->parent_cObj->calc($this->mconf['begin'] ? $this->mconf['begin'] : $this->conf['begin']);
         $minItemsConf = isset($this->mconf['minItems.']) ? $this->mconf['minItems.'] : (isset($this->conf['minItems.']) ? $this->conf['minItems.'] : NULL);
         $minItems = is_array($minItemsConf) ? $this->parent_cObj->stdWrap($minItems, $minItemsConf) : $minItems;
         $maxItemsConf = isset($this->mconf['maxItems.']) ? $this->mconf['maxItems.'] : (isset($this->conf['maxItems.']) ? $this->conf['maxItems.'] : NULL);
         $maxItems = is_array($maxItemsConf) ? $this->parent_cObj->stdWrap($maxItems, $maxItemsConf) : $maxItems;
         $beginConf = isset($this->mconf['begin.']) ? $this->mconf['begin.'] : (isset($this->conf['begin.']) ? $this->conf['begin.'] : NULL);
         $begin = is_array($beginConf) ? $this->parent_cObj->stdWrap($begin, $beginConf) : $begin;
         $banUidArray = $this->getBannedUids();
         // Fill in the menuArr with elements that should go into the menu:
         $this->menuArr = array();
         foreach ($temp as $data) {
             $spacer = GeneralUtility::inList($this->spacerIDList, $data['doktype']) || $data['ITEM_STATE'] === 'SPC' ? 1 : 0;
             // if item is a spacer, $spacer is set
             if ($this->filterMenuPages($data, $banUidArray, $spacer)) {
                 $c_b++;
                 // If the beginning item has been reached.
                 if ($begin <= $c_b) {
                     $this->menuArr[$c] = $data;
                     $this->menuArr[$c]['isSpacer'] = $spacer;
                     $c++;
                     if ($maxItems && $c >= $maxItems) {
                         break;
                     }
                 }
             }
         }
         // Fill in fake items, if min-items is set.
         if ($minItems) {
             while ($c < $minItems) {
                 $this->menuArr[$c] = array('title' => '...', 'uid' => $GLOBALS['TSFE']->id);
                 $c++;
             }
         }
         //	Passing the menuArr through a user defined function:
         if ($this->mconf['itemArrayProcFunc']) {
             if (!is_array($this->parentMenuArr)) {
                 $this->parentMenuArr = array();
             }
             $this->menuArr = $this->userProcess('itemArrayProcFunc', $this->menuArr);
         }
         // Setting number of menu items
         $GLOBALS['TSFE']->register['count_menuItems'] = count($this->menuArr);
         $this->hash = md5(serialize($this->menuArr) . serialize($this->mconf) . serialize($this->tmpl->rootLine) . serialize($this->MP_array));
         // Get the cache timeout:
         if ($this->conf['cache_period']) {
             $cacheTimeout = $this->conf['cache_period'];
         } else {
             $cacheTimeout = $GLOBALS['TSFE']->get_cache_timeout();
         }
         $cache = $this->getCache();
         $cachedData = $cache->get($this->hash);
         if (!is_array($cachedData)) {
             $this->generate();
             $cache->set($this->hash, $this->result, array('ident_MENUDATA'), (int) $cacheTimeout);
         } else {
             $this->result = $cachedData;
         }
         // End showAccessRestrictedPages
         if ($this->mconf['showAccessRestrictedPages']) {
             // RESTORING where_groupAccess
             $this->sys_page->where_groupAccess = $SAVED_where_groupAccess;
         }
     }
 }
 /**
  * Fetches all menuitems if special = keywords is set
  *
  * @param string $specialValue The value from special.value
  * @param string $sortingField The sorting field
  * @return array
  */
 protected function prepareMenuItemsForKeywordsMenu($specialValue, $sortingField)
 {
     $tsfe = $this->getTypoScriptFrontendController();
     $menuItems = array();
     list($specialValue) = GeneralUtility::intExplode(',', $specialValue);
     if (!$specialValue) {
         $specialValue = $tsfe->page['uid'];
     }
     if ($this->conf['special.']['setKeywords'] || $this->conf['special.']['setKeywords.']) {
         $kw = isset($this->conf['special.']['setKeywords.']) ? $this->parent_cObj->stdWrap($this->conf['special.']['setKeywords'], $this->conf['special.']['setKeywords.']) : $this->conf['special.']['setKeywords'];
     } else {
         // The page record of the 'value'.
         $value_rec = $this->sys_page->getPage($specialValue);
         $kfieldSrc = $this->conf['special.']['keywordsField.']['sourceField'] ? $this->conf['special.']['keywordsField.']['sourceField'] : 'keywords';
         // keywords.
         $kw = trim($this->parent_cObj->keywords($value_rec[$kfieldSrc]));
     }
     // *'auto', 'manual', 'tstamp'
     $mode = $this->conf['special.']['mode'];
     switch ($mode) {
         case 'starttime':
             $sortField = 'starttime';
             break;
         case 'lastUpdated':
         case 'manual':
             $sortField = 'lastUpdated';
             break;
         case 'tstamp':
             $sortField = 'tstamp';
             break;
         case 'crdate':
             $sortField = 'crdate';
             break;
         default:
             $sortField = 'SYS_LASTCHANGED';
     }
     // Depth, limit, extra where
     if (MathUtility::canBeInterpretedAsInteger($this->conf['special.']['depth'])) {
         $depth = MathUtility::forceIntegerInRange($this->conf['special.']['depth'], 0, 20);
     } else {
         $depth = 20;
     }
     // Max number of items
     $limit = MathUtility::forceIntegerInRange($this->conf['special.']['limit'], 0, 100);
     $extraWhere = ' AND pages.uid<>' . $specialValue . ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0') . $this->getDoktypeExcludeWhere();
     if ($this->conf['special.']['excludeNoSearchPages']) {
         $extraWhere .= ' AND pages.no_search=0';
     }
     // Start point
     $eLevel = $this->parent_cObj->getKey(isset($this->conf['special.']['entryLevel.']) ? $this->parent_cObj->stdWrap($this->conf['special.']['entryLevel'], $this->conf['special.']['entryLevel.']) : $this->conf['special.']['entryLevel'], $this->tmpl->rootLine);
     $startUid = (int) $this->tmpl->rootLine[$eLevel]['uid'];
     // Which field is for keywords
     $kfield = 'keywords';
     if ($this->conf['special.']['keywordsField']) {
         list($kfield) = explode(' ', trim($this->conf['special.']['keywordsField']));
     }
     // If there are keywords and the startuid is present
     if ($kw && $startUid) {
         $bA = MathUtility::forceIntegerInRange($this->conf['special.']['beginAtLevel'], 0, 100);
         $id_list = $this->parent_cObj->getTreeList(-1 * $startUid, $depth - 1 + $bA, $bA - 1);
         $kwArr = explode(',', $kw);
         $keyWordsWhereArr = array();
         foreach ($kwArr as $word) {
             $word = trim($word);
             if ($word) {
                 $keyWordsWhereArr[] = $kfield . ' LIKE \'%' . $this->getDatabaseConnection()->quoteStr($word, 'pages') . '%\'';
             }
         }
         $where = empty($keyWordsWhereArr) ? '' : '(' . implode(' OR ', $keyWordsWhereArr) . ')';
         $res = $this->parent_cObj->exec_getQuery('pages', array('pidInList' => '0', 'uidInList' => $id_list, 'where' => $where . $extraWhere, 'orderBy' => $sortingField ?: $sortField . ' desc', 'max' => $limit));
         while ($row = $this->getDatabaseConnection()->sql_fetch_assoc($res)) {
             $tsfe->sys_page->versionOL('pages', $row, true);
             if (is_array($row)) {
                 $menuItems[$row['uid']] = $this->sys_page->getPageOverlay($row);
             }
         }
         $this->getDatabaseConnection()->sql_free_result($res);
     }
     return $menuItems;
 }
    /**
     * Execute final query, based on phash integer list. The main point is sorting the result in the right order.
     *
     * @param 	string		List of phash integers which match the search.
     * @param 	integer		Pointer to which indexing configuration you want to search in. -1 means no filtering. 0 means only regular indexed content.
     * @return 	pointer		Query result pointer
     */
    protected function execFinalQuery($list, $freeIndexUid = -1)
    {
        // Setting up methods of filtering results
        // based on page types, access, etc.
        $page_join = '';
        $page_where = '';
        // Indexing configuration clause:
        $freeIndexUidClause = $this->freeIndexUidWhere($freeIndexUid);
        // Calling hook for alternative creation of page ID list
        if ($hookObj = $this->hookRequest('execFinalQuery_idList')) {
            $page_where = $hookObj->execFinalQuery_idList($list);
        }
        // Alternative to getting all page ids by ->getTreeList() where
        // "excludeSubpages" is NOT respected.
        if ($this->joinPagesForQuery) {
            $page_join = ',
				pages';
            $page_where = ' AND pages.uid = ISEC.page_id
				' . $this->enableFields('pages') . '
				AND pages.no_search=0
				AND pages.doktype<200
			';
        } elseif ($this->searchRootPageIdList >= 0) {
            // Collecting all pages IDs in which to search;
            // filtering out ALL pages that are not accessible due to enableFields.
            // Does NOT look for "no_search" field!
            $siteIdNumbers = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $this->searchRootPageIdList);
            $pageIdList = array();
            foreach ($siteIdNumbers as $rootId) {
                $pageIdList[] = \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::getTreeList($rootId, 9999, 0, 0, '', '') . $rootId;
            }
            $page_where = ' AND ISEC.page_id IN (' . implode(',', $pageIdList) . ')';
        }
        // otherwise select all / disable everything
        // If any of the ranking sortings are selected, we must make a
        // join with the word/rel-table again, because we need to
        // calculate ranking based on all search-words found.
        if (substr($this->sortOrder, 0, 5) == 'rank_') {
            switch ($this->sortOrder) {
                case 'rank_flag':
                    // This gives priority to word-position (max-value) so that words in title, keywords, description counts more than in content.
                    // The ordering is refined with the frequency sum as well.
                    $grsel = 'MAX(IR.flags) AS order_val1, SUM(IR.freq) AS order_val2';
                    $orderBy = 'order_val1' . $this->getDescendingSortOrderFlag() . ', order_val2' . $this->getDescendingSortOrderFlag();
                    break;
                case 'rank_first':
                    // Results in average position of search words on page.
                    // Must be inversely sorted (low numbers are closer to top)
                    $grsel = 'AVG(IR.first) AS order_val';
                    $orderBy = 'order_val' . $this->getDescendingSortOrderFlag(TRUE);
                    break;
                case 'rank_count':
                    // Number of words found
                    $grsel = 'SUM(IR.count) AS order_val';
                    $orderBy = 'order_val' . $this->getDescendingSortOrderFlag();
                    break;
                default:
                    // Frequency sum. I'm not sure if this is the best way to do
                    // it (make a sum...). Or should it be the average?
                    $grsel = 'SUM(IR.freq) AS order_val';
                    $orderBy = 'order_val' . $this->getDescendingSortOrderFlag();
                    break;
            }
            $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('ISEC.*, IP.*, ' . $grsel, 'index_words IW,
							index_rel IR,
							index_section ISEC,
							index_phash IP' . $page_join, 'IP.phash IN (' . $list . ') ' . $this->mediaTypeWhere() . $this->languageWhere() . $freeIndexUidClause . '
							AND IW.wid=IR.wid
							AND ISEC.phash = IR.phash
							AND IP.phash = IR.phash' . $page_where, 'IP.phash,ISEC.phash,ISEC.phash_t3,ISEC.rl0,ISEC.rl1,ISEC.rl2 ,ISEC.page_id,ISEC.uniqid,IP.phash_grouping,IP.data_filename ,IP.data_page_id ,IP.data_page_reg1,IP.data_page_type,IP.data_page_mp,IP.gr_list,IP.item_type,IP.item_title,IP.item_description,IP.item_mtime,IP.tstamp,IP.item_size,IP.contentHash,IP.crdate,IP.parsetime,IP.sys_language_uid,IP.item_crdate,IP.cHashParams,IP.externalUrl,IP.recordUid,IP.freeIndexUid,IP.freeIndexSetId', $orderBy);
        } else {
            // Otherwise, if sorting are done with the pages table or other fields,
            // there is no need for joining with the rel/word tables:
            $orderBy = '';
            switch ((string) $this->sortOrder) {
                case 'title':
                    $orderBy = 'IP.item_title' . $this->getDescendingSortOrderFlag();
                    break;
                case 'crdate':
                    $orderBy = 'IP.item_crdate' . $this->getDescendingSortOrderFlag();
                    break;
                case 'mtime':
                    $orderBy = 'IP.item_mtime' . $this->getDescendingSortOrderFlag();
                    break;
            }
            $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('ISEC.*, IP.*', 'index_phash IP,index_section ISEC' . $page_join, 'IP.phash IN (' . $list . ') ' . $this->mediaTypeWhere() . $this->languageWhere() . $freeIndexUidClause . '
							AND IP.phash = ISEC.phash' . $page_where, 'IP.phash,ISEC.phash,ISEC.phash_t3,ISEC.rl0,ISEC.rl1,ISEC.rl2 ,ISEC.page_id,ISEC.uniqid,IP.phash_grouping,IP.data_filename ,IP.data_page_id ,IP.data_page_reg1,IP.data_page_type,IP.data_page_mp,IP.gr_list,IP.item_type,IP.item_title,IP.item_description,IP.item_mtime,IP.tstamp,IP.item_size,IP.contentHash,IP.crdate,IP.parsetime,IP.sys_language_uid,IP.item_crdate,IP.cHashParams,IP.externalUrl,IP.recordUid,IP.freeIndexUid,IP.freeIndexSetId', $orderBy);
        }
        return $res;
    }
Exemplo n.º 7
0
 /**
  * renders a recursive pidList to reference content from a list of pages
  */
 public function user_getTreeList()
 {
     $GLOBALS['TSFE']->register['pidInList'] = trim($this->cObj->data['uid'] . ',' . ($GLOBALS['TSFE']->register['tt_content_shortcut_recursive'] ? $this->cObj->getTreeList($this->cObj->data['uid'], $GLOBALS['TSFE']->register['tt_content_shortcut_recursive']) : ''), ',');
 }