[BUGFIX] use search word(s) for ordering search results (again) 94/20294/3
authorRalf Hettinger <ng@ralfhettinger.de>
Mon, 29 Apr 2013 10:31:06 +0000 (12:31 +0200)
committerMarkus Klein <klein.t3@mfc-linz.at>
Thu, 9 Jan 2014 00:07:46 +0000 (01:07 +0100)
There has been a regression in http://review.typo3.org/6657 which
removes correlation between searched words and ordering of search
results. Therefore the ordering of search results had nothing to do
with the search term anymore. This is fixed hereby by using the code
parts from prior versions.

Resolves: #38767
Releases: 6.2, 6.1, 6.0, 4.7
Change-Id: I9cfaceaeede38456dd7622085879c1bd0648be85
Reviewed-on: https://review.typo3.org/20294
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
Reviewed-by: Wouter Wolters
Reviewed-by: Markus Klein
Tested-by: Markus Klein
typo3/sysext/indexed_search/Classes/Controller/SearchFormController.php

index e4ce04e..50ce45b 100644 (file)
@@ -122,6 +122,12 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
         */
        public $domain_records = array();
 
+       // Select clauses for individual words
+       /**
+        * @todo Define visibility
+        */
+       public $wSelClauses = array();
+
        // Domain records (?)
        /**
         * @todo Define visibility
@@ -918,6 +924,7 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
                $wildcard_left = $mode & self::WILDCARD_LEFT ? '%' : '';
                $wildcard_right = $mode & self::WILDCARD_RIGHT ? '%' : '';
                $wSel = 'IW.baseword LIKE \'' . $wildcard_left . $GLOBALS['TYPO3_DB']->quoteStr($sWord, 'index_words') . $wildcard_right . '\'';
+               $this->wSelClauses[] = $wSel;
                $res = $this->execPHashListQuery($wSel, ' AND is_stopword=0');
                return $res;
        }
@@ -931,6 +938,7 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
         */
        public function searchDistinct($sWord) {
                $wSel = 'IW.wid=' . \TYPO3\CMS\IndexedSearch\Utility\IndexedSearchUtility::md5inthash($sWord);
+               $this->wSelClauses[] = $wSel;
                $res = $this->execPHashListQuery($wSel, ' AND is_stopword=0');
                return $res;
        }
@@ -946,6 +954,7 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
                $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('ISEC.phash', 'index_section ISEC, index_fulltext IFT', 'IFT.fulltextdata LIKE \'%' . $GLOBALS['TYPO3_DB']->quoteStr($sSentence, 'index_fulltext') . '%\' AND
                                ISEC.phash = IFT.phash
                        ' . $this->sectionTableWhere(), 'ISEC.phash');
+               $this->wSelClauses[] = '1=1';
                return $res;
        }
 
@@ -958,6 +967,7 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
         */
        public function searchMetaphone($sWord) {
                $wSel = 'IW.metaphone=' . $sWord;
+               $this->wSelClauses[] = $wSel;
                $res = $this->execPHashListQuery($wSel, ' AND is_stopword=0');
        }
 
@@ -1150,14 +1160,26 @@ class SearchFormController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin {
                                        $grsel = 'SUM(IR.freq) AS order_val';
                                        $orderBy = 'order_val' . $this->isDescending();
                        }
-                       $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
-                                                       AND ' . $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);
+
+                       // So, words are imploded into an OR statement (no "sentence search" should be done here - may deselect results)
+                       $wordSel = '(' . implode(' OR ', $this->wSelClauses) . ') AND ';
+
+                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                               'ISEC.*, IP.*, ' . $grsel,
+                               'index_words IW,
+                                       index_rel IR,
+                                       index_section ISEC,
+                                       index_phash IP' . $page_join,
+                               $wordSel .
+                               'IP.phash IN (' . $list . ') ' .
+                                       $this->mediaTypeWhere() . ' ' . $this->languageWhere() . $freeIndexUidClause . '
+                                       AND IW.wid=IR.wid
+                                       AND ISEC.phash = IR.phash
+                                       AND IP.phash = IR.phash
+                                       AND ' . $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 = '';