/** * check if an allowed tag (defined in a filteroption) was found in the current result list * * @param string $tag The tag to match against the searchresult * @return boolean TRUE if tag was found. Else FALSE */ public function checkIfTagMatchesRecords($tag) { // if tag list is empty, fetch them from the result list // otherwise use the cached result list if (!$this->tagsInSearchResult) { $this->tagsInSearchResult = $this->pObj->tagsInSearchResult = $this->db->getTagsFromSearchResult(); $GLOBALS['TSFE']->fe_user->setKey('ses', 'ke_search.tagsInSearchResults', $tagsInSearchResult); } return array_key_exists($tag, $this->tagsInSearchResult); }
/** * The main entry point of this class * It will return the complete sorting HTML * * @return string HTML */ public function renderSorting() { // show sorting: // if show Sorting is activated in FlexForm // if a value to sortBy is set in FlexForm (title, relevance, sortdate, what ever...) // if there are any entries in current search results if ($this->conf['showSortInFrontend'] && !empty($this->conf['sortByVisitor']) && $this->pObj->numberOfResults) { // loop all allowed orderings foreach ($this->sortBy as $field) { // we can't sort by score if there is no sword given if ($this->pObj->sword != '' || $field != 'score') { $sortByDir = $this->getDefaultSortingDirection($field); if (TYPO3_VERSION_INTEGER >= 7000000) { $dbOrdering = TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(' ', $this->db->getOrdering()); } else { $dbOrdering = t3lib_div::trimExplode(' ', $this->db->getOrdering()); } /* if ordering direction is the same change it * * Explaintation: * No ordering is active. Default Ordering by db is "sortdate desc". * Default ordering by current field is also "sortdate desc". * So...if you click the link for sortdate it will sort the results by "sortdate desc" again * To prevent this we change the default ordering here */ if ($field == $dbOrdering[0] && $sortByDir == $dbOrdering[1]) { $sortByDir = $this->changeOrdering($sortByDir); } $markerArray['###FIELDNAME###'] = $field; $markerArray['###URL###'] = $this->generateSortingLink($field, $sortByDir); $markerArray['###CLASS###'] = $this->getClassNameForUpDownArrow($field, $dbOrdering); $links .= $this->cObj->substituteMarkerArray($this->subpartArray['###SORT_LINK###'], $markerArray); } } $content = $this->cObj->substituteSubpart($this->subpartArray['###ORDERNAVIGATION###'], '###SORT_LINK###', $links); $content = $this->cObj->substituteMarker($content, '###LABEL_SORT###', $this->pObj->pi_getLL('label_sort')); return $content; } else { return ''; } }
/** * creates the search result list * 1. does the actual searching (fetches the results to $rows) * 2. fills fluid variables for fluid templates to $this->fluidTemplateVariables * */ public function getSearchResults() { // fetch the search results $limit = $this->db->getLimit(); $rows = $this->db->getSearchResults(); // TODO: Check how Sphinx handles this, seems to return full result set if (count($rows) > $limit[1]) { $rows = array_slice($rows, $limit[0], $limit[1]); } // set number of results $this->numberOfResults = $this->db->getAmountOfSearchResults(); // count searchword with ke_stats $this->countSearchWordWithKeStats($this->sword); // count search phrase in ke_search statistic tables if ($this->conf['countSearchPhrases']) { $this->countSearchPhrase($this->sword, $this->swords, $this->numberOfResults, $this->tagsAgainst); } // render "no results" text and stop here if ($this->numberOfResults == 0) { return $this->setNoResultsText(); } // set switch for too short words $this->fluidTemplateVariables['wordsTooShort'] = $this->hasTooShortWords ? 1 : 0; // init counter and loop through the search results $resultCount = 1; $this->searchResult = GeneralUtility::makeInstance('tx_kesearch_lib_searchresult', $this); $this->fluidTemplateVariables['resultrows'] = array(); foreach ($rows as $row) { $this->searchResult->setRow($row); $tempMarkerArray = array('orig_uid' => $row['orig_uid'], 'orig_pid' => $row['orig_pid'], 'title' => $this->searchResult->getTitle(), 'teaser' => $this->searchResult->getTeaser()); // hook for additional markers in result row if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalResultMarker'])) { // make curent row number available to hook $this->currentRowNumber = $resultCount; foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalResultMarker'] as $_classRef) { $_procObj =& GeneralUtility::getUserObj($_classRef); $_procObj->additionalResultMarker($tempMarkerArray, $row, $this); } unset($this->currentRowNumber); } // add type marker // for file results just use the "file" type, not the file extension (eg. "file:pdf") list($type) = explode(':', $row['type']); $tempMarkerArray['type'] = str_replace(' ', '_', $type); // use the markers array as a base for the fluid template values $resultrowTemplateValues = $tempMarkerArray; // set result url $resultUrl = $this->searchResult->getResultUrl($this->conf['renderResultUrlAsLink']); $resultrowTemplateValues['url'] = $resultUrl; // set result numeration $resultNumber = $resultCount + $this->piVars['page'] * $this->conf['resultsPerPage'] - $this->conf['resultsPerPage']; $resultrowTemplateValues['number'] = $resultNumber; // set score (used for plain score output and score scale) $resultScore = number_format($row['score'], 2, ',', ''); $resultrowTemplateValues['score'] = $resultScore; // set date (formatted and raw as a timestamp) $resultDate = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['sortdate']); $resultrowTemplateValues['date'] = $resultDate; $resultrowTemplateValues['date_timestamp'] = $row['sortdate']; // set percental score $resultrowTemplateValues['percent'] = $row['percent']; // show tags? $tags = $row['tags']; $tags = str_replace('#', ' ', $tags); $resultrowTemplateValues['tags'] = $tags; // set preview image $renderedImage = $this->renderPreviewImageOrTypeIcon($row); $resultrowTemplateValues['imageHtml'] = $renderedImage; // set end date for cal events if ($type == 'cal') { $resultrowTemplateValues['cal'] = $this->getCalEventEnddate($row['orig_uid']); } // add result row to the variables array $this->fluidTemplateVariables['resultrows'][] = $resultrowTemplateValues; // increase result counter $resultCount++; } }
/** * creates the search result list * 1. does the actual searching (fetches the results to $rows) * 2. fills the marker for marker based templating and renders the resultlist * 3. fills fluid variables for fluid based templating to $this->fluidTemplateVariables * * @return string rendered searchbox (for static or ajax templating, not for fluid templating) */ public function getSearchResults() { // generate and add onload image $this->onloadImage = $this->createHideSpinner(); // fetch the search results $limit = $this->db->getLimit(); $rows = $this->db->getSearchResults(); // TODO: Check how Sphinx handles this, seems to return full result set if (count($rows) > $limit[1]) { $rows = array_slice($rows, $limit[0], $limit[1]); } // set number of results $this->numberOfResults = $this->db->getAmountOfSearchResults(); // count searchword with ke_stats $this->countSearchWordWithKeStats($this->sword); // count search phrase in ke_search statistic tables if ($this->conf['countSearchPhrases']) { $this->countSearchPhrase($this->sword, $this->swords, $this->numberOfResults, $this->tagsAgainst); } // render "no results" text and stop here if ($this->numberOfResults == 0) { return $this->renderNoResultsText(); } if ($this->hasTooShortWords) { $content = $this->renderTooShortWordsText(); $this->fluidTemplateVariables['wordsTooShort'] = 1; } // init counter and loop through the search results $resultCount = 1; $this->searchResult = GeneralUtility::makeInstance('tx_kesearch_lib_searchresult', $this); $this->fluidTemplateVariables['resultrows'] = array(); foreach ($rows as $row) { // generate row content $tempContent = $this->cObj->getSubpart($this->templateCode, '###RESULT_ROW###'); $this->searchResult->setRow($row); $tempMarkerArray = array('title' => $this->searchResult->getTitle(), 'teaser' => $this->searchResult->getTeaser()); // hook for additional markers in result (only valid for maker based templating) if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalResultMarker'])) { // make curent row number available to hook $this->currentRowNumber = $resultCount; foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalResultMarker'] as $_classRef) { $_procObj =& GeneralUtility::getUserObj($_classRef); $_procObj->additionalResultMarker($tempMarkerArray, $row, $this); } unset($this->currentRowNumber); } // add type marker // for file results just use the "file" type, not the file extension (eg. "file:pdf") list($type) = explode(':', $row['type']); $tempMarkerArray['type'] = str_replace(' ', '_', $type); // replace markers $tempContent = $this->cObj->substituteMarkerArray($tempContent, $tempMarkerArray, $wrap = '###|###', $uppercase = 1); $resultrowTemplateValues = $tempMarkerArray; // show result url? $resultUrl = $this->searchResult->getResultUrl($this->conf['renderResultUrlAsLink']); if ($this->conf['showResultUrl']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_RESULTURL###'); $subContent = $this->cObj->substituteMarker($subContent, '###LABEL_RESULTURL###', $this->pi_getLL('label_resulturl')); $subContent = $this->cObj->substituteMarker($subContent, '###RESULTURL###', $resultUrl); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_RESULTURL###', $subContent, $recursive = 1); $resultrowTemplateValues['url'] = $resultUrl; // show result numeration? $resultNumber = $resultCount + $this->piVars['page'] * $this->conf['resultsPerPage'] - $this->conf['resultsPerPage']; if ($this->conf['resultsNumeration']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_NUMERATION###'); $subContent = $this->cObj->substituteMarker($subContent, '###NUMBER###', $resultNumber); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_NUMERATION###', $subContent, $recursive = 1); $resultrowTemplateValues['number'] = $resultNumber; // show score? $resultScore = number_format($row['score'], 2, ',', ''); if ($this->conf['showScore'] && $row['score']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_SCORE###'); $subContent = $this->cObj->substituteMarker($subContent, '###LABEL_SCORE###', $this->pi_getLL('label_score')); $subContent = $this->cObj->substituteMarker($subContent, '###SCORE###', $resultScore); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_SCORE###', $subContent, $recursive = 1); $resultrowTemplateValues['score'] = $resultScore; // show date? $resultDate = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['sortdate']); if ($this->conf['showDate'] && $row['sortdate']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_DATE###'); $subContent = $this->cObj->substituteMarker($subContent, '###LABEL_DATE###', $this->pi_getLL('label_date')); $subContent = $this->cObj->substituteMarker($subContent, '###DATE###', $resultDate); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_DATE###', $subContent, $recursive = 1); $resultrowTemplateValues['date'] = $resultDate; // show percental score? if ($this->conf['showPercentalScore'] && $row['percent']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_SCORE_PERCENT###'); $subContent = $this->cObj->substituteMarker($subContent, '###LABEL_SCORE_PERCENT###', $this->pi_getLL('label_score_percent')); $subContent = $this->cObj->substituteMarker($subContent, '###SCORE_PERCENT###', $row['percent']); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_SCORE_PERCENT###', $subContent, $recursive = 1); $resultrowTemplateValues['percent'] = $row['percent']; // show score scale? if ($this->conf['showScoreScale'] && $row['percent']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_SCORE_SCALE###'); $subContent = $this->cObj->substituteMarker($subContent, '###SCORE###', $row['percent']); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_SCORE_SCALE###', $subContent, $recursive = 1); // show tags? $tags = $row['tags']; $tags = str_replace('#', ' ', $tags); if ($this->conf['showTags']) { $subContent = $this->cObj->getSubpart($this->templateCode, '###SUB_TAGS###'); $subContent = $this->cObj->substituteMarker($subContent, '###LABEL_TAGS###', $this->pi_getLL('label_tags')); $subContent = $this->cObj->substituteMarker($subContent, '###TAGS###', htmlspecialchars($tags)); } else { $subContent = ''; } $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_TAGS###', $subContent, $recursive = 1); $resultrowTemplateValues['tags'] = $tags; // preview image $renderedImage = $this->renderPreviewImageOrTypeIcon($row); $resultrowTemplateValues['imageHtml'] = $renderedImage[0]; $tempContent = $this->cObj->substituteSubpart($tempContent, '###SUB_TYPE_ICON###', $renderedImage[1], $recursive = 1); // fluid templating: add result row to the variables array $this->fluidTemplateVariables['resultrows'][] = $resultrowTemplateValues; // marker based templating: add temp content to result list $content .= $tempContent; // increase result counter $resultCount++; } // hook for additional content AFTER the result list if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalContentAfterResultList'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalContentAfterResultList'] as $_classRef) { $_procObj =& GeneralUtility::getUserObj($_classRef); $content .= $_procObj->additionalContentAfterResultList($this); } } // add onload image if in AJAX mode if ($this->conf['renderMethod'] != 'static') { $content .= $this->onloadImage; } return $content; }
/** * Test ordering if a searchword was given * - show sorting in FE is allowed * - admin presorts are uninteresting * - FE-User is allowed to choose between sortdate,tstamp and title * - allowed piVars are given * * @test */ public function checkOrderingWithSearchwordAndUserCanSortWithAllowedPiVars() { $this->pObj->sword = 'Hallo'; $this->pObj->conf = array('sortWithoutSearchword' => 'tstamp asc', 'showSortInFrontend' => true, 'sortByVisitor' => 'sortdate,tstamp,title', 'sortByAdmin' => 'sortdate desc'); $this->pObj->piVars = array('orderByField' => 'title', 'orderByDir' => 'asc'); $this->pObj->piVars = $this->div->cleanPiVars($this->pObj->piVars); $db = new tx_kesearch_db($this->pObj); $this->assertEquals('title asc', $db->getOrdering()); }