[TASK] Move MysqlFulltextIndexHook to EXT:indexed_search_mysql 96/33296/2
authorGeorg Ringer <georg.ringer@gmail.com>
Mon, 13 Oct 2014 19:44:32 +0000 (21:44 +0200)
committerMarkus Klein <klein.t3@reelworx.at>
Mon, 13 Oct 2014 21:30:14 +0000 (23:30 +0200)
The hook MysqlFulltextIndexHook should be moved from indexed_search to
indexed_search_mysql because it is only used if indexed_search_mysql is activated.

Resolves: #62201
Releases: master
Change-Id: I11d61f771abb2d2431c26156fb1d6e0104cba5c9
Reviewed-on: http://review.typo3.org/33296
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Markus Klein <klein.t3@reelworx.at>
Tested-by: Markus Klein <klein.t3@reelworx.at>
typo3/sysext/indexed_search/Classes/Hook/MysqlFulltextIndexHook.php [deleted file]
typo3/sysext/indexed_search_mysql/Classes/Hook/MysqlFulltextIndexHook.php [new file with mode: 0644]
typo3/sysext/indexed_search_mysql/ext_localconf.php

diff --git a/typo3/sysext/indexed_search/Classes/Hook/MysqlFulltextIndexHook.php b/typo3/sysext/indexed_search/Classes/Hook/MysqlFulltextIndexHook.php
deleted file mode 100644 (file)
index d671b60..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-namespace TYPO3\CMS\IndexedSearch\Hook;
-
-/**
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-/**
- * Class that hooks into Indexed Search and replaces standard SQL queries with MySQL fulltext index queries.
- *
- * @author     Michael Stucki <michael@typo3.org>
- */
-class MysqlFulltextIndexHook {
-
-       /**
-        * @var \TYPO3\CMS\IndexedSearch\Controller\SearchFormController
-        */
-       public $pObj;
-
-       const ANY_PART_OF_THE_WORD = '1';
-       const LAST_PART_OF_THE_WORD = '2';
-       const FIRST_PART_OF_THE_WORD = '3';
-       const SOUNDS_LIKE = '10';
-       const SENTENCE = '20';
-       /**
-        * Gets a SQL result pointer to traverse for the search records.
-        *
-        * @param array $searchWordsArray Search words
-        * @param integer $freeIndexUid Pointer to which indexing configuration you want to search in. -1 means no filtering. 0 means only regular indexed content.
-        * @return boolean|\mysqli_result|object MySQLi result object / DBAL object
-        */
-       public function getResultRows_SQLpointer($searchWordsArray, $freeIndexUid = -1) {
-               // Build the search string, detect which fulltext index to use, and decide whether boolean search is needed or not
-               $searchData = $this->getSearchString($searchWordsArray);
-               // Perform SQL Search / collection of result rows array:
-               $resource = FALSE;
-               if ($searchData) {
-                       // Do the search:
-                       $GLOBALS['TT']->push('execFinalQuery');
-                       $resource = $this->execFinalQuery_fulltext($searchData, $freeIndexUid);
-                       $GLOBALS['TT']->pull();
-               }
-               return $resource;
-       }
-
-       /**
-        * Returns a search string for use with MySQL FULLTEXT query
-        *
-        * @param array $searchWordArray Search word array
-        * @return string Search string
-        */
-       public function getSearchString($searchWordArray) {
-               // Initialize variables:
-               $count = 0;
-               $searchBoolean = FALSE;
-               // Change this to TRUE to force BOOLEAN SEARCH MODE (useful if fulltext index is still empty)
-               $fulltextIndex = 'index_fulltext.fulltextdata';
-               $naturalSearchString = '';
-               // This holds the result if the search is natural (doesn't contain any boolean operators)
-               $booleanSearchString = '';
-               // This holds the result if the search is boolen (contains +/-/| operators)
-               $searchType = (string) $this->pObj->piVars['type'];
-               // Traverse searchwords and prefix them with corresponding operator
-               foreach ($searchWordArray as $searchWordData) {
-                       // Making the query for a single search word based on the search-type
-                       $searchWord = $searchWordData['sword'];
-                       $wildcard = '';
-                       if (strstr($searchWord, ' ')) {
-                               $searchType = self::SENTENCE;
-                       }
-                       switch ($searchType) {
-                               case self::ANY_PART_OF_THE_WORD:
-
-                               case self::LAST_PART_OF_THE_WORD:
-
-                               case self::FIRST_PART_OF_THE_WORD:
-                                       // First part of word
-                                       $wildcard = '*';
-                                       // Part-of-word search requires boolean mode!
-                                       $searchBoolean = TRUE;
-                                       break;
-                               case self::SOUNDS_LIKE:
-                                       $indexerObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\IndexedSearch\\Indexer');
-                                       // Initialize the indexer-class
-                                       /** @var \TYPO3\CMS\IndexedSearch\Indexer $indexerObj */
-                                       $searchWord = $indexerObj->metaphone($searchWord, $indexerObj->storeMetaphoneInfoAsWords);
-                                       unset($indexerObj);
-                                       $fulltextIndex = 'index_fulltext.metaphonedata';
-                                       break;
-                               case self::SENTENCE:
-                                       $searchBoolean = TRUE;
-                                       // Remove existing quotes and fix misplaced quotes.
-                                       $searchWord = trim(str_replace('"', ' ', $searchWord));
-                                       break;
-                               }
-                               // Perform search for word:
-                               switch ($searchWordData['oper']) {
-                                       case 'AND NOT':
-                                               $booleanSearchString .= ' -' . $searchWord . $wildcard;
-                                               $searchBoolean = TRUE;
-                                               break;
-                                       case 'OR':
-                                               $booleanSearchString .= ' ' . $searchWord . $wildcard;
-                                               $searchBoolean = TRUE;
-                                               break;
-                                       default:
-                                               $booleanSearchString .= ' +' . $searchWord . $wildcard;
-                                               $naturalSearchString .= ' ' . $searchWord;
-                       }
-                       $count++;
-               }
-               if ($searchType == self::SENTENCE) {
-                       $searchString = '"' . trim($naturalSearchString) . '"';
-               } elseif ($searchBoolean) {
-                       $searchString = trim($booleanSearchString);
-               } else {
-                       $searchString = trim($naturalSearchString);
-               }
-               return array(
-                       'searchBoolean' => $searchBoolean,
-                       'searchString' => $searchString,
-                       'fulltextIndex' => $fulltextIndex
-               );
-       }
-
-       /**
-        * Execute final query, based on phash integer list. The main point is sorting the result in the right order.
-        *
-        * @param array $searchData Array with search string, boolean indicator, and fulltext index reference
-        * @param integer $freeIndexUid Pointer to which indexing configuration you want to search in. -1 means no filtering. 0 means only regular indexed content.
-        * @return boolean|\mysqli_result|object MySQLi result object / DBAL object
-        */
-       protected function execFinalQuery_fulltext($searchData, $freeIndexUid = -1) {
-               // Setting up methods of filtering results based on page types, access, etc.
-               $pageJoin = '';
-               // Indexing configuration clause:
-               $freeIndexUidClause = $this->pObj->freeIndexUidWhere($freeIndexUid);
-               // Calling hook for alternative creation of page ID list
-               if ($hookObj = &$this->pObj->hookRequest('execFinalQuery_idList')) {
-                       $pageWhere = $hookObj->execFinalQuery_idList('');
-               } elseif ($this->pObj->join_pages) {
-                       // Alternative to getting all page ids by ->getTreeList() where "excludeSubpages" is NOT respected.
-                       $pageJoin = ',
-                               pages';
-                       $pageWhere = 'pages.uid = ISEC.page_id
-                               ' . $this->pObj->cObj->enableFields('pages') . '
-                               AND pages.no_search=0
-                               AND pages.doktype<200
-                       ';
-               } elseif ($this->pObj->wholeSiteIdList >= 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->pObj->wholeSiteIdList);
-                       $idList = array();
-                       foreach ($siteIdNumbers as $rootId) {
-                               /** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
-                               $cObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
-                               $idList[] = $cObj->getTreeList( -1 * $rootId, 9999);
-                       }
-                       $pageWhere = ' ISEC.page_id IN (' . implode(',', $idList) . ')';
-               } else {
-                       // Disable everything... (select all)
-                       $pageWhere = ' 1=1';
-               }
-               $searchBoolean = '';
-               if ($searchData['searchBoolean']) {
-                       $searchBoolean = ' IN BOOLEAN MODE';
-               }
-               $resource = $GLOBALS['TYPO3_DB']->exec_SELECTquery('index_fulltext.*, ISEC.*, IP.*', 'index_fulltext, index_section ISEC, index_phash IP' . $pageJoin, 'MATCH (' . $searchData['fulltextIndex'] . ') AGAINST (' . $GLOBALS['TYPO3_DB']->fullQuoteStr($searchData['searchString'], 'index_fulltext') . $searchBoolean . ') ' . $this->pObj->mediaTypeWhere() . ' ' . $this->pObj->languageWhere() . $freeIndexUidClause . '
-                                       AND index_fulltext.phash = IP.phash
-                                       AND ISEC.phash = IP.phash
-                                       AND ' . $pageWhere, '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');
-               return $resource;
-       }
-
-}
diff --git a/typo3/sysext/indexed_search_mysql/Classes/Hook/MysqlFulltextIndexHook.php b/typo3/sysext/indexed_search_mysql/Classes/Hook/MysqlFulltextIndexHook.php
new file mode 100644 (file)
index 0000000..9adb780
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+namespace TYPO3\CMS\IndexedSearchMysql\Hook;
+
+/**
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+/**
+ * Class that hooks into Indexed Search and replaces standard SQL queries with MySQL fulltext index queries.
+ *
+ * @author     Michael Stucki <michael@typo3.org>
+ */
+class MysqlFulltextIndexHook {
+
+       /**
+        * @var \TYPO3\CMS\IndexedSearch\Controller\SearchFormController
+        */
+       public $pObj;
+
+       const ANY_PART_OF_THE_WORD = '1';
+       const LAST_PART_OF_THE_WORD = '2';
+       const FIRST_PART_OF_THE_WORD = '3';
+       const SOUNDS_LIKE = '10';
+       const SENTENCE = '20';
+       /**
+        * Gets a SQL result pointer to traverse for the search records.
+        *
+        * @param array $searchWordsArray Search words
+        * @param integer $freeIndexUid Pointer to which indexing configuration you want to search in. -1 means no filtering. 0 means only regular indexed content.
+        * @return boolean|\mysqli_result|object MySQLi result object / DBAL object
+        */
+       public function getResultRows_SQLpointer($searchWordsArray, $freeIndexUid = -1) {
+               // Build the search string, detect which fulltext index to use, and decide whether boolean search is needed or not
+               $searchData = $this->getSearchString($searchWordsArray);
+               // Perform SQL Search / collection of result rows array:
+               $resource = FALSE;
+               if ($searchData) {
+                       // Do the search:
+                       $GLOBALS['TT']->push('execFinalQuery');
+                       $resource = $this->execFinalQuery_fulltext($searchData, $freeIndexUid);
+                       $GLOBALS['TT']->pull();
+               }
+               return $resource;
+       }
+
+       /**
+        * Returns a search string for use with MySQL FULLTEXT query
+        *
+        * @param array $searchWordArray Search word array
+        * @return string Search string
+        */
+       public function getSearchString($searchWordArray) {
+               // Initialize variables:
+               $count = 0;
+               $searchBoolean = FALSE;
+               // Change this to TRUE to force BOOLEAN SEARCH MODE (useful if fulltext index is still empty)
+               $fulltextIndex = 'index_fulltext.fulltextdata';
+               $naturalSearchString = '';
+               // This holds the result if the search is natural (doesn't contain any boolean operators)
+               $booleanSearchString = '';
+               // This holds the result if the search is boolen (contains +/-/| operators)
+               $searchType = (string) $this->pObj->piVars['type'];
+               // Traverse searchwords and prefix them with corresponding operator
+               foreach ($searchWordArray as $searchWordData) {
+                       // Making the query for a single search word based on the search-type
+                       $searchWord = $searchWordData['sword'];
+                       $wildcard = '';
+                       if (strstr($searchWord, ' ')) {
+                               $searchType = self::SENTENCE;
+                       }
+                       switch ($searchType) {
+                               case self::ANY_PART_OF_THE_WORD:
+
+                               case self::LAST_PART_OF_THE_WORD:
+
+                               case self::FIRST_PART_OF_THE_WORD:
+                                       // First part of word
+                                       $wildcard = '*';
+                                       // Part-of-word search requires boolean mode!
+                                       $searchBoolean = TRUE;
+                                       break;
+                               case self::SOUNDS_LIKE:
+                                       $indexerObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\IndexedSearch\\Indexer');
+                                       // Initialize the indexer-class
+                                       /** @var \TYPO3\CMS\IndexedSearch\Indexer $indexerObj */
+                                       $searchWord = $indexerObj->metaphone($searchWord, $indexerObj->storeMetaphoneInfoAsWords);
+                                       unset($indexerObj);
+                                       $fulltextIndex = 'index_fulltext.metaphonedata';
+                                       break;
+                               case self::SENTENCE:
+                                       $searchBoolean = TRUE;
+                                       // Remove existing quotes and fix misplaced quotes.
+                                       $searchWord = trim(str_replace('"', ' ', $searchWord));
+                                       break;
+                               }
+                               // Perform search for word:
+                               switch ($searchWordData['oper']) {
+                                       case 'AND NOT':
+                                               $booleanSearchString .= ' -' . $searchWord . $wildcard;
+                                               $searchBoolean = TRUE;
+                                               break;
+                                       case 'OR':
+                                               $booleanSearchString .= ' ' . $searchWord . $wildcard;
+                                               $searchBoolean = TRUE;
+                                               break;
+                                       default:
+                                               $booleanSearchString .= ' +' . $searchWord . $wildcard;
+                                               $naturalSearchString .= ' ' . $searchWord;
+                       }
+                       $count++;
+               }
+               if ($searchType == self::SENTENCE) {
+                       $searchString = '"' . trim($naturalSearchString) . '"';
+               } elseif ($searchBoolean) {
+                       $searchString = trim($booleanSearchString);
+               } else {
+                       $searchString = trim($naturalSearchString);
+               }
+               return array(
+                       'searchBoolean' => $searchBoolean,
+                       'searchString' => $searchString,
+                       'fulltextIndex' => $fulltextIndex
+               );
+       }
+
+       /**
+        * Execute final query, based on phash integer list. The main point is sorting the result in the right order.
+        *
+        * @param array $searchData Array with search string, boolean indicator, and fulltext index reference
+        * @param integer $freeIndexUid Pointer to which indexing configuration you want to search in. -1 means no filtering. 0 means only regular indexed content.
+        * @return boolean|\mysqli_result|object MySQLi result object / DBAL object
+        */
+       protected function execFinalQuery_fulltext($searchData, $freeIndexUid = -1) {
+               // Setting up methods of filtering results based on page types, access, etc.
+               $pageJoin = '';
+               // Indexing configuration clause:
+               $freeIndexUidClause = $this->pObj->freeIndexUidWhere($freeIndexUid);
+               // Calling hook for alternative creation of page ID list
+               if ($hookObj = &$this->pObj->hookRequest('execFinalQuery_idList')) {
+                       $pageWhere = $hookObj->execFinalQuery_idList('');
+               } elseif ($this->pObj->join_pages) {
+                       // Alternative to getting all page ids by ->getTreeList() where "excludeSubpages" is NOT respected.
+                       $pageJoin = ',
+                               pages';
+                       $pageWhere = 'pages.uid = ISEC.page_id
+                               ' . $this->pObj->cObj->enableFields('pages') . '
+                               AND pages.no_search=0
+                               AND pages.doktype<200
+                       ';
+               } elseif ($this->pObj->wholeSiteIdList >= 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->pObj->wholeSiteIdList);
+                       $idList = array();
+                       foreach ($siteIdNumbers as $rootId) {
+                               /** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
+                               $cObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
+                               $idList[] = $cObj->getTreeList( -1 * $rootId, 9999);
+                       }
+                       $pageWhere = ' ISEC.page_id IN (' . implode(',', $idList) . ')';
+               } else {
+                       // Disable everything... (select all)
+                       $pageWhere = ' 1=1';
+               }
+               $searchBoolean = '';
+               if ($searchData['searchBoolean']) {
+                       $searchBoolean = ' IN BOOLEAN MODE';
+               }
+               $resource = $GLOBALS['TYPO3_DB']->exec_SELECTquery('index_fulltext.*, ISEC.*, IP.*', 'index_fulltext, index_section ISEC, index_phash IP' . $pageJoin, 'MATCH (' . $searchData['fulltextIndex'] . ') AGAINST (' . $GLOBALS['TYPO3_DB']->fullQuoteStr($searchData['searchString'], 'index_fulltext') . $searchBoolean . ') ' . $this->pObj->mediaTypeWhere() . ' ' . $this->pObj->languageWhere() . $freeIndexUidClause . '
+                                       AND index_fulltext.phash = IP.phash
+                                       AND ISEC.phash = IP.phash
+                                       AND ' . $pageWhere, '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');
+               return $resource;
+       }
+
+}
index 981ad1d..bd6d721 100644 (file)
@@ -2,6 +2,6 @@
 defined('TYPO3_MODE') or die();
 
 // Configure hook to query the fulltext index
-$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['pi1_hooks']['getResultRows_SQLpointer'] = '&TYPO3\CMS\IndexedSearch\Hook\MysqlFulltextIndexHook';
+$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['pi1_hooks']['getResultRows_SQLpointer'] = '&TYPO3\CMS\IndexedSearchMysql\Hook\MysqlFulltextIndexHook';
 // Use all index_* tables except "index_rel" and "index_words"
 $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['indexed_search']['use_tables'] = 'index_phash,index_fulltext,index_section,index_grlist,index_stat_search,index_stat_word,index_debug,index_config';