PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/kernel/classes/ezsearch.php

https://github.com/aurelienRT1/ezpublish
PHP | 600 lines | 411 code | 91 blank | 98 comment | 109 complexity | b4e035fcfeb67f868dd0085d1ce31429 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. //
  3. // Definition of eZSearch class
  4. //
  5. // Created on: <25-Jun-2002 10:56:09 bf>
  6. //
  7. // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
  8. // SOFTWARE NAME: eZ Publish
  9. // SOFTWARE RELEASE: 4.1.x
  10. // COPYRIGHT NOTICE: Copyright (C) 1999-2010 eZ Systems AS
  11. // SOFTWARE LICENSE: GNU General Public License v2.0
  12. // NOTICE: >
  13. // This program is free software; you can redistribute it and/or
  14. // modify it under the terms of version 2.0 of the GNU General
  15. // Public License as published by the Free Software Foundation.
  16. //
  17. // This program is distributed in the hope that it will be useful,
  18. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. // GNU General Public License for more details.
  21. //
  22. // You should have received a copy of version 2.0 of the GNU General
  23. // Public License along with this program; if not, write to the Free
  24. // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  25. // MA 02110-1301, USA.
  26. //
  27. //
  28. // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
  29. //
  30. /*!
  31. \class eZSearch
  32. \ingroup eZKernel
  33. \brief eZSearch handles indexing of objects to the search engine
  34. */
  35. class eZSearch
  36. {
  37. function eZSearch()
  38. {
  39. }
  40. /*!
  41. \static
  42. determine how to pass the commit argument, for deletes and updates
  43. maybe this needs to be further splitted
  44. */
  45. static function needCommit()
  46. {
  47. $searchEngine = eZSearch::getEngine();
  48. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'needCommit'))
  49. {
  50. return $searchEngine->needCommit();
  51. }
  52. else
  53. {
  54. return true;
  55. }
  56. }
  57. /*!
  58. \static
  59. See if a remove is needed in an update of content objects
  60. */
  61. static function needRemoveWithUpdate()
  62. {
  63. $searchEngine = eZSearch::getEngine();
  64. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'needRemoveWithUpdate'))
  65. {
  66. return $searchEngine->needRemoveWithUpdate();
  67. }
  68. else
  69. {
  70. return true;
  71. }
  72. }
  73. /*!
  74. \static
  75. Will remove the index from the given object from the search engine
  76. A commit parameter is added since 4.1 to accomodate requirements of several search plugins
  77. */
  78. static function removeObject( $contentObject, $commit = true )
  79. {
  80. $searchEngine = eZSearch::getEngine();
  81. if ( is_object( $searchEngine ) )
  82. {
  83. $searchEngine->removeObject( $contentObject, $commit );
  84. }
  85. }
  86. /*!
  87. \static
  88. Will index the content object to the search engine.
  89. A commit parameter is added since 4.1 to accomodate requirements of several search plugins
  90. */
  91. static function addObject( $contentObject, $commit = true )
  92. {
  93. $searchEngine = eZSearch::getEngine();
  94. if ( is_object( $searchEngine ) )
  95. {
  96. $searchEngine->addObject( $contentObject, $commit );
  97. }
  98. }
  99. /*!
  100. \static
  101. Runs a query to the search engine.
  102. */
  103. static function search( $searchText, $params, $searchTypes = array() )
  104. {
  105. $searchEngine = eZSearch::getEngine();
  106. if ( is_object( $searchEngine ) )
  107. {
  108. return $searchEngine->search( $searchText, $params, $searchTypes );
  109. }
  110. }
  111. /*!
  112. \static
  113. */
  114. static function normalizeText( $text )
  115. {
  116. $searchEngine = eZSearch::getEngine();
  117. if ( is_object( $searchEngine ) )
  118. {
  119. return $searchEngine->normalizeText( $text );
  120. }
  121. return '';
  122. }
  123. /*!
  124. \static
  125. returns search parameters in array based on supported search types and post variables
  126. */
  127. static function buildSearchArray()
  128. {
  129. $searchEngine = eZSearch::getEngine();
  130. $searchArray = array();
  131. $andSearchParts = array();
  132. $searchTypesDefinition = array( 'types' => array(), 'general_filter' => array() );
  133. if ( is_object( $searchEngine ) )
  134. {
  135. // This method was renamed in pre 3.5 trunk
  136. if ( method_exists( $searchEngine, 'supportedSearchTypes' ) )
  137. {
  138. $searchTypesDefinition = $searchEngine->supportedSearchTypes(); // new and correct
  139. }
  140. else
  141. {
  142. $searchTypesDefinition = $searchEngine->suportedSearchTypes(); // deprecated
  143. }
  144. }
  145. $http = eZHTTPTool::instance();
  146. foreach ( $searchTypesDefinition['types'] as $searchType )
  147. {
  148. $postVariablePrefix = 'Content_search_' . $searchType['type'] . '_' . $searchType['subtype'] . '_';
  149. //print $postVariablePrefix . "\n";
  150. //print_r( $searchType['params'] );
  151. $searchArrayPartForType = array();
  152. $searchPart = array();
  153. $valuesFetched = false;
  154. $valuesMissing = false;
  155. foreach ( $searchType['params'] as $parameter )
  156. {
  157. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $postVariablePrefix . $parameter,
  158. 'post variable to check' );
  159. if ( $http->hasVariable( $postVariablePrefix . $parameter ) )
  160. {
  161. $values = $http->variable( $postVariablePrefix . $parameter );
  162. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $values, 'fetched values' );
  163. foreach ( $values as $i => $value )
  164. {
  165. $searchArrayPartForType[$i][$parameter] = $values[$i];
  166. $valuesFetched = true;
  167. }
  168. }
  169. else
  170. {
  171. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $postVariablePrefix . $parameter,
  172. 'post variable does not exist' );
  173. $valuesMissing = true;
  174. break;
  175. }
  176. }
  177. if ( $valuesFetched == true && $valuesMissing == false )
  178. {
  179. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', 'adding values to search' );
  180. foreach ( array_keys( $searchArrayPartForType ) as $key )
  181. {
  182. $part =& $searchArrayPartForType[$key];
  183. $part['type'] = $searchType['type'];
  184. $part['subtype'] = $searchType['subtype'];
  185. if ( $part['type'] == 'attribute' )
  186. {
  187. // Remove incomplete search parts from the search.
  188. // An incomplete search part is for instance an empty text field,
  189. // or a select box with no selected values.
  190. // This functionality has been moved to the search engine.
  191. // Checking if it is defined in the search engine
  192. if ( method_exists( $searchEngine, 'isSearchPartIncomplete' ) )
  193. {
  194. $removePart = $searchEngine->isSearchPartIncomplete( $part );
  195. }
  196. else // for backwards compatibility
  197. {
  198. $removePart = false;
  199. switch ( $part['subtype'] )
  200. {
  201. case 'fulltext':
  202. {
  203. if ( !isset( $part['value'] ) || $part['value'] == '' )
  204. $removePart = true;
  205. }
  206. break;
  207. case 'patterntext':
  208. {
  209. if ( !isset( $part['value'] ) || $part['value'] == '' )
  210. $removePart = true;
  211. }
  212. break;
  213. case 'integer':
  214. {
  215. if ( !isset( $part['value'] ) || $part['value'] == '' )
  216. $removePart = true;
  217. }
  218. break;
  219. case 'integers':
  220. {
  221. if ( !isset( $part['values'] ) || count( $part['values'] ) == 0 )
  222. $removePart = true;
  223. }
  224. break;
  225. case 'byrange':
  226. {
  227. if ( !isset( $part['from'] ) || $part['from'] == '' ||
  228. !isset( $part['to'] ) || $part['to'] == '' )
  229. $removePart = true;
  230. }
  231. break;
  232. case 'byidentifier':
  233. {
  234. if ( !isset( $part['value'] ) || $part['value'] == '' )
  235. $removePart = true;
  236. }
  237. break;
  238. case 'byidentifierrange':
  239. {
  240. if ( !isset( $part['from'] ) || $part['from'] == '' ||
  241. !isset( $part['to'] ) || $part['to'] == '' )
  242. $removePart = true;
  243. }
  244. break;
  245. case 'integersbyidentifier':
  246. {
  247. if ( !isset( $part['values'] ) || count( $part['values'] ) == 0 )
  248. $removePart = true;
  249. }
  250. break;
  251. case 'byarea':
  252. {
  253. if ( !isset( $part['from'] ) || $part['from'] == '' ||
  254. !isset( $part['to'] ) || $part['to'] == '' ||
  255. !isset( $part['minvalue'] ) || $part['minvalue'] == '' ||
  256. !isset( $part['maxvalue'] ) || $part['maxvalue'] == '' )
  257. {
  258. $removePart = true;
  259. }
  260. }
  261. }
  262. }
  263. if ( $removePart )
  264. {
  265. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $searchArrayPartForType[$key],
  266. 'removing incomplete search part' );
  267. unSet( $searchArrayPartForType[$key] );
  268. }
  269. }
  270. }
  271. $andSearchParts = array_merge( $andSearchParts, $searchArrayPartForType );
  272. }
  273. }
  274. $generalFilter = array();
  275. foreach ( $searchTypesDefinition['general_filter'] as $searchType )
  276. {
  277. $postVariablePrefix = 'Content_search_' . $searchType['type'] . '_' . $searchType['subtype'] . '_';
  278. $searchArrayPartForType = array();
  279. $searchPart = array();
  280. $valuesFetched = false;
  281. $valuesMissing = false;
  282. foreach ( $searchType['params'] as $parameter )
  283. {
  284. $varName = '';
  285. $paramName = '';
  286. if ( is_array( $parameter ) )
  287. {
  288. $varName = $postVariablePrefix . $parameter['value'];
  289. $paramName = $parameter['value'];
  290. }
  291. else
  292. {
  293. $varName = $postVariablePrefix . $parameter;
  294. $paramName = $parameter;
  295. }
  296. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $varName,
  297. 'post variable to check' );
  298. if ( $http->hasVariable( $varName ) )
  299. {
  300. $values = $http->variable( $varName );
  301. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $values, 'fetched values' );
  302. $searchArrayPartForType[$paramName] = $values;
  303. $valuesFetched = true;
  304. }
  305. else
  306. {
  307. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $varName,
  308. 'post variable does not exist' );
  309. $valuesMissing = true;
  310. break;
  311. }
  312. }
  313. if ( $valuesFetched == true && $valuesMissing == false )
  314. {
  315. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', 'adding values to search' );
  316. $part =& $searchArrayPartForType;
  317. $part['type'] = $searchType['type'];
  318. $part['subtype'] = $searchType['subtype'];
  319. if ( $part['type'] == 'general' )
  320. {
  321. // Remove incomplete search parts from the search.
  322. // An incomplete search part is for instance an empty text field,
  323. // or a select box with no selected values.
  324. $removePart = false;
  325. switch ( $part['subtype'] )
  326. {
  327. case 'class':
  328. {
  329. if ( !isset( $part['value'] ) ||
  330. ( is_array( $part['value'] ) && count( $part['value'] ) == 0 ) ||
  331. ( !is_array( $part['value'] ) && $part['value'] == '' ) )
  332. $removePart = true;
  333. }
  334. break;
  335. case 'publishdate':
  336. {
  337. if ( !isset( $part['value'] ) ||
  338. ( is_array( $part['value'] ) && count( $part['value'] ) == 0 ) ||
  339. ( !is_array( $part['value'] ) && $part['value'] == '' ) )
  340. $removePart = true;
  341. }
  342. break;
  343. case 'subtree':
  344. {
  345. if ( !isset( $part['value'] ) ||
  346. ( is_array( $part['value'] ) && count( $part['value'] ) == 0 ) ||
  347. ( !is_array( $part['value'] ) && $part['value'] == '' ) )
  348. $removePart = true;
  349. }
  350. break;
  351. }
  352. if ( $removePart )
  353. {
  354. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $searchArrayPartForType[$key],
  355. 'removing incomplete search part' );
  356. unSet( $searchArrayPartForType[$key] );
  357. continue;
  358. }
  359. }
  360. $generalFilter = array_merge( $generalFilter, array( $searchArrayPartForType ) );
  361. }
  362. }
  363. if ( $andSearchParts != null )
  364. {
  365. $searchArray['and'] = $andSearchParts;
  366. }
  367. if ( $generalFilter != null )
  368. {
  369. $searchArray['general'] = $generalFilter;
  370. }
  371. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $searchArray, 'search array' );
  372. return $searchArray;
  373. }
  374. /*!
  375. \static
  376. Tells the current search engine to cleanup up all data.
  377. */
  378. static function cleanup()
  379. {
  380. $searchEngine = eZSearch::getEngine();
  381. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'cleanup' ) )
  382. {
  383. $searchEngine->cleanup();
  384. }
  385. }
  386. /*!
  387. \static
  388. Get object instance of eZSearch engine to use.
  389. \return instance of eZSearch class.
  390. */
  391. static function getEngine()
  392. {
  393. // Get instance if already created.
  394. $instanceName = 'eZSearchPlugin_' . $GLOBALS['eZCurrentAccess'];
  395. if ( isset( $GLOBALS[$instanceName] ) )
  396. {
  397. return $GLOBALS[$instanceName];
  398. }
  399. $ini = eZINI::instance();
  400. $searchEngineString = 'ezsearch';
  401. if ( $ini->hasVariable( 'SearchSettings', 'SearchEngine' ) == true )
  402. {
  403. $searchEngineString = $ini->variable( 'SearchSettings', 'SearchEngine' );
  404. }
  405. $directoryList = array();
  406. if ( $ini->hasVariable( 'SearchSettings', 'ExtensionDirectories' ) )
  407. {
  408. $extensionDirectories = $ini->variable( 'SearchSettings', 'ExtensionDirectories' );
  409. if ( is_array( $extensionDirectories ) )
  410. {
  411. $directoryList = eZExtension::expandedPathList( $extensionDirectories, 'search/plugins' );
  412. }
  413. }
  414. $kernelDir = array( 'kernel/search/plugins' );
  415. $directoryList = array_merge( $kernelDir, $directoryList );
  416. foreach( $directoryList as $directory )
  417. {
  418. $searchEngineFile = implode( '/', array( $directory, strtolower( $searchEngineString ), strtolower( $searchEngineString ) ) ) . '.php';
  419. if ( file_exists( $searchEngineFile ) )
  420. {
  421. eZDebugSetting::writeDebug( 'kernel-search-ezsearch', 'Loading search engine from ' . $searchEngineFile, 'eZSearch::getEngine' );
  422. include_once( $searchEngineFile );
  423. $GLOBALS[$instanceName] = new $searchEngineString();
  424. return $GLOBALS[$instanceName];
  425. }
  426. }
  427. eZDebug::writeDebug( 'Unable to find the search engine:' . $searchEngineString, 'eZSearch' );
  428. eZDebug::writeDebug( 'Tried paths: ' . implode( ', ', $directoryList ), 'eZSearch' );
  429. return false;
  430. }
  431. /*
  432. * @since eZ Publish 4.1
  433. * @description new methods that search plugins can implement when meta data is updated (outside publish operations)
  434. *
  435. */
  436. public static function updateNodeSection( $nodeID, $sectionID )
  437. {
  438. $searchEngine = eZSearch::getEngine();
  439. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'updateNodeSection'))
  440. {
  441. return $searchEngine->updateNodeSection( $nodeID, $sectionID );
  442. }
  443. return false;
  444. }
  445. public static function updateNodeVisibility( $nodeID, $action )
  446. {
  447. $searchEngine = eZSearch::getEngine();
  448. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'updateNodeVisibility'))
  449. {
  450. return $searchEngine->updateNodeVisibility( $nodeID, $action );
  451. }
  452. return false;
  453. }
  454. public static function addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList )
  455. {
  456. $searchEngine = eZSearch::getEngine();
  457. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'addNodeAssignment'))
  458. {
  459. return $searchEngine->addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList );
  460. }
  461. return false;
  462. }
  463. public static function removeNodeAssignment( $mainNodeID, $newMainNodeID, $objectID, $nodeAssigmentIDList )
  464. {
  465. $searchEngine = eZSearch::getEngine();
  466. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'removeNodeAssignment'))
  467. {
  468. return $searchEngine->removeNodeAssignment( $mainNodeID, $newMainNodeID, $objectID, $nodeAssigmentIDList );
  469. }
  470. return false;
  471. }
  472. /**
  473. * Removes nodes from the search engine.
  474. *
  475. * @param array $nodeIdList Array of node ID to remove.
  476. *
  477. * @return false in case of error, otherwise return the result of the search engine call
  478. */
  479. public static function removeNodes( array $nodeIdList )
  480. {
  481. $searchEngine = self::getEngine();
  482. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'removeNodes' ) )
  483. {
  484. return $searchEngine->removeNodes( $nodeIdList );
  485. }
  486. return false;
  487. }
  488. public static function updateObjectState( $objectID, $objectStateList )
  489. {
  490. $searchEngine = eZSearch::getEngine();
  491. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'updateObjectState'))
  492. {
  493. return $searchEngine->updateObjectState( $objectID, $objectStateList );
  494. }
  495. return false;
  496. }
  497. public static function swapNode( $nodeID, $selectedNodeID, $nodeIdList = array() )
  498. {
  499. $searchEngine = eZSearch::getEngine();
  500. if ( is_object( $searchEngine ) && method_exists( $searchEngine, 'swapNode'))
  501. {
  502. return $searchEngine->swapNode( $nodeID, $selectedNodeID, $nodeIdList = array() );
  503. }
  504. return false;
  505. }
  506. }
  507. ?>