|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZSearch class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package kernel 00009 */ 00010 00011 /*! 00012 \class eZSearch 00013 \ingroup eZKernel 00014 \brief eZSearch handles indexing of objects to the search engine 00015 00016 */ 00017 00018 class eZSearch 00019 { 00020 function eZSearch() 00021 { 00022 00023 } 00024 00025 /*! 00026 \static 00027 determine how to pass the commit argument, for deletes and updates 00028 maybe this needs to be further splitted 00029 */ 00030 00031 static function needCommit() 00032 { 00033 $searchEngine = eZSearch::getEngine(); 00034 00035 if ( $searchEngine instanceof ezpSearchEngine ) 00036 { 00037 return $searchEngine->needCommit(); 00038 } 00039 return true; 00040 } 00041 /*! 00042 \static 00043 See if a remove is needed in an update of content objects 00044 */ 00045 00046 static function needRemoveWithUpdate() 00047 { 00048 $searchEngine = eZSearch::getEngine(); 00049 00050 if ( $searchEngine instanceof ezpSearchEngine ) 00051 { 00052 return $searchEngine->needRemoveWithUpdate(); 00053 } 00054 return true; 00055 } 00056 00057 /** 00058 * Removes object $contentObject from the search database. 00059 * 00060 * @param eZContentObject $contentObject the content object to remove 00061 * @param bool $commit Whether to commit after removing the object 00062 * @return bool True if the operation succeed. 00063 */ 00064 static function removeObject( $contentObject, $commit = true ) 00065 { 00066 $searchEngine = eZSearch::getEngine(); 00067 00068 if ( $searchEngine instanceof ezpSearchEngine ) 00069 { 00070 return $searchEngine->removeObject( $contentObject, $commit ); 00071 } 00072 00073 return false; 00074 } 00075 00076 /** 00077 * Adds object $contentObject to the search database. 00078 * 00079 * @param eZContentObject $contentObject Object to add to search engine 00080 * @param bool $commit Whether to commit after adding the object 00081 * @return bool True if the operation succeed. 00082 */ 00083 static function addObject( $contentObject, $commit = true ) 00084 { 00085 $searchEngine = eZSearch::getEngine(); 00086 00087 if ( $searchEngine instanceof ezpSearchEngine ) 00088 { 00089 return $searchEngine->addObject( $contentObject, $commit ); 00090 } 00091 00092 return false; 00093 } 00094 00095 /*! 00096 \static 00097 Runs a query to the search engine. 00098 */ 00099 static function search( $searchText, $params, $searchTypes = array() ) 00100 { 00101 $searchEngine = eZSearch::getEngine(); 00102 00103 if ( $searchEngine instanceof ezpSearchEngine ) 00104 { 00105 return $searchEngine->search( $searchText, $params, $searchTypes ); 00106 } 00107 } 00108 00109 /*! 00110 \static 00111 */ 00112 static function normalizeText( $text ) 00113 { 00114 $searchEngine = eZSearch::getEngine(); 00115 00116 if ( $searchEngine instanceof ezpSearchEngine ) 00117 { 00118 return $searchEngine->normalizeText( $text ); 00119 } 00120 00121 return ''; 00122 } 00123 00124 /*! 00125 \static 00126 returns search parameters in array based on supported search types and post variables 00127 */ 00128 static function buildSearchArray() 00129 { 00130 $searchEngine = eZSearch::getEngine(); 00131 00132 $searchArray = array(); 00133 $andSearchParts = array(); 00134 $searchTypesDefinition = array( 'types' => array(), 'general_filter' => array() ); 00135 00136 if ( $searchEngine instanceof ezpSearchEngine ) 00137 { 00138 // This method was renamed in pre 3.5 trunk 00139 if ( method_exists( $searchEngine, 'supportedSearchTypes' ) ) 00140 { 00141 $searchTypesDefinition = $searchEngine->supportedSearchTypes(); // new and correct 00142 } 00143 else 00144 { 00145 $searchTypesDefinition = $searchEngine->suportedSearchTypes(); // deprecated 00146 } 00147 } 00148 00149 $http = eZHTTPTool::instance(); 00150 00151 foreach ( $searchTypesDefinition['types'] as $searchType ) 00152 { 00153 $postVariablePrefix = 'Content_search_' . $searchType['type'] . '_' . $searchType['subtype'] . '_'; 00154 //print $postVariablePrefix . "\n"; 00155 //print_r( $searchType['params'] ); 00156 $searchArrayPartForType = array(); 00157 00158 $searchPart = array(); 00159 $valuesFetched = false; 00160 $valuesMissing = false; 00161 foreach ( $searchType['params'] as $parameter ) 00162 { 00163 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $postVariablePrefix . $parameter, 00164 'post variable to check' ); 00165 00166 if ( $http->hasVariable( $postVariablePrefix . $parameter ) ) 00167 { 00168 $values = $http->variable( $postVariablePrefix . $parameter ); 00169 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $values, 'fetched values' ); 00170 00171 foreach ( $values as $i => $value ) 00172 { 00173 $searchArrayPartForType[$i][$parameter] = $values[$i]; 00174 $valuesFetched = true; 00175 } 00176 } 00177 else 00178 { 00179 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $postVariablePrefix . $parameter, 00180 'post variable does not exist' ); 00181 $valuesMissing = true; 00182 break; 00183 } 00184 } 00185 00186 if ( $valuesFetched == true && $valuesMissing == false ) 00187 { 00188 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', 'adding values to search' ); 00189 foreach ( array_keys( $searchArrayPartForType ) as $key ) 00190 { 00191 $part =& $searchArrayPartForType[$key]; 00192 $part['type'] = $searchType['type']; 00193 $part['subtype'] = $searchType['subtype']; 00194 00195 if ( $part['type'] == 'attribute' ) 00196 { 00197 // Remove incomplete search parts from the search. 00198 // An incomplete search part is for instance an empty text field, 00199 // or a select box with no selected values. 00200 00201 // This functionality has been moved to the search engine. 00202 // Checking if it is defined in the search engine 00203 if ( method_exists( $searchEngine, 'isSearchPartIncomplete' ) ) 00204 { 00205 $removePart = $searchEngine->isSearchPartIncomplete( $part ); 00206 } 00207 else // for backwards compatibility 00208 { 00209 $removePart = false; 00210 switch ( $part['subtype'] ) 00211 { 00212 case 'fulltext': 00213 { 00214 if ( !isset( $part['value'] ) || $part['value'] == '' ) 00215 $removePart = true; 00216 } 00217 break; 00218 00219 case 'patterntext': 00220 { 00221 if ( !isset( $part['value'] ) || $part['value'] == '' ) 00222 $removePart = true; 00223 } 00224 break; 00225 00226 case 'integer': 00227 { 00228 if ( !isset( $part['value'] ) || $part['value'] == '' ) 00229 $removePart = true; 00230 } 00231 break; 00232 00233 case 'integers': 00234 { 00235 if ( !isset( $part['values'] ) || count( $part['values'] ) == 0 ) 00236 $removePart = true; 00237 } 00238 break; 00239 00240 case 'byrange': 00241 { 00242 if ( !isset( $part['from'] ) || $part['from'] == '' || 00243 !isset( $part['to'] ) || $part['to'] == '' ) 00244 $removePart = true; 00245 } 00246 break; 00247 00248 case 'byidentifier': 00249 { 00250 if ( !isset( $part['value'] ) || $part['value'] == '' ) 00251 $removePart = true; 00252 } 00253 break; 00254 00255 case 'byidentifierrange': 00256 { 00257 if ( !isset( $part['from'] ) || $part['from'] == '' || 00258 !isset( $part['to'] ) || $part['to'] == '' ) 00259 $removePart = true; 00260 } 00261 break; 00262 00263 case 'integersbyidentifier': 00264 { 00265 if ( !isset( $part['values'] ) || count( $part['values'] ) == 0 ) 00266 $removePart = true; 00267 } 00268 break; 00269 00270 case 'byarea': 00271 { 00272 if ( !isset( $part['from'] ) || $part['from'] == '' || 00273 !isset( $part['to'] ) || $part['to'] == '' || 00274 !isset( $part['minvalue'] ) || $part['minvalue'] == '' || 00275 !isset( $part['maxvalue'] ) || $part['maxvalue'] == '' ) 00276 { 00277 $removePart = true; 00278 } 00279 } 00280 } 00281 } 00282 00283 if ( $removePart ) 00284 { 00285 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $searchArrayPartForType[$key], 00286 'removing incomplete search part' ); 00287 unSet( $searchArrayPartForType[$key] ); 00288 } 00289 } 00290 } 00291 $andSearchParts = array_merge( $andSearchParts, $searchArrayPartForType ); 00292 } 00293 } 00294 $generalFilter = array(); 00295 foreach ( $searchTypesDefinition['general_filter'] as $searchType ) 00296 { 00297 00298 $postVariablePrefix = 'Content_search_' . $searchType['type'] . '_' . $searchType['subtype'] . '_'; 00299 00300 $searchArrayPartForType = array(); 00301 00302 $searchPart = array(); 00303 $valuesFetched = false; 00304 $valuesMissing = false; 00305 00306 foreach ( $searchType['params'] as $parameter ) 00307 { 00308 $varName = ''; 00309 $paramName = ''; 00310 if ( is_array( $parameter ) ) 00311 { 00312 $varName = $postVariablePrefix . $parameter['value']; 00313 $paramName = $parameter['value']; 00314 } 00315 else 00316 { 00317 $varName = $postVariablePrefix . $parameter; 00318 $paramName = $parameter; 00319 } 00320 00321 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $varName, 00322 'post variable to check' ); 00323 00324 if ( $http->hasVariable( $varName ) ) 00325 { 00326 $values = $http->variable( $varName ); 00327 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $values, 'fetched values' ); 00328 $searchArrayPartForType[$paramName] = $values; 00329 $valuesFetched = true; 00330 00331 } 00332 else 00333 { 00334 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $varName, 00335 'post variable does not exist' ); 00336 $valuesMissing = true; 00337 break; 00338 } 00339 } 00340 00341 if ( $valuesFetched == true && $valuesMissing == false ) 00342 { 00343 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', 'adding values to search' ); 00344 00345 $part =& $searchArrayPartForType; 00346 00347 $part['type'] = $searchType['type']; 00348 $part['subtype'] = $searchType['subtype']; 00349 00350 if ( $part['type'] == 'general' ) 00351 { 00352 // Remove incomplete search parts from the search. 00353 // An incomplete search part is for instance an empty text field, 00354 // or a select box with no selected values. 00355 $removePart = false; 00356 switch ( $part['subtype'] ) 00357 { 00358 case 'class': 00359 { 00360 if ( !isset( $part['value'] ) || 00361 ( is_array( $part['value'] ) && count( $part['value'] ) == 0 ) || 00362 ( !is_array( $part['value'] ) && $part['value'] == '' ) ) 00363 $removePart = true; 00364 } 00365 break; 00366 case 'publishdate': 00367 { 00368 if ( !isset( $part['value'] ) || 00369 ( is_array( $part['value'] ) && count( $part['value'] ) == 0 ) || 00370 ( !is_array( $part['value'] ) && $part['value'] == '' ) ) 00371 $removePart = true; 00372 } 00373 break; 00374 case 'subtree': 00375 { 00376 if ( !isset( $part['value'] ) || 00377 ( is_array( $part['value'] ) && count( $part['value'] ) == 0 ) || 00378 ( !is_array( $part['value'] ) && $part['value'] == '' ) ) 00379 00380 $removePart = true; 00381 } 00382 break; 00383 } 00384 00385 if ( $removePart ) 00386 { 00387 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $searchArrayPartForType[$key], 00388 'removing incomplete search part' ); 00389 unSet( $searchArrayPartForType[$key] ); 00390 continue; 00391 } 00392 } 00393 00394 $generalFilter = array_merge( $generalFilter, array( $searchArrayPartForType ) ); 00395 } 00396 00397 00398 } 00399 00400 if ( $andSearchParts != null ) 00401 { 00402 $searchArray['and'] = $andSearchParts; 00403 } 00404 if ( $generalFilter != null ) 00405 { 00406 $searchArray['general'] = $generalFilter; 00407 } 00408 00409 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', $searchArray, 'search array' ); 00410 return $searchArray; 00411 } 00412 00413 /*! 00414 \static 00415 Tells the current search engine to cleanup up all data. 00416 */ 00417 static function cleanup() 00418 { 00419 $searchEngine = eZSearch::getEngine(); 00420 00421 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'cleanup' ) ) 00422 { 00423 $searchEngine->cleanup(); 00424 } 00425 } 00426 00427 /*! 00428 \static 00429 Get object instance of eZSearch engine to use. 00430 00431 \return instance of eZSearch class. 00432 */ 00433 static function getEngine() 00434 { 00435 // Get instance if already created. 00436 $instanceName = "eZSearchPlugin_" . $GLOBALS["eZCurrentAccess"]["name"]; 00437 if ( isset( $GLOBALS[$instanceName] ) ) 00438 { 00439 return $GLOBALS[$instanceName]; 00440 } 00441 00442 $ini = eZINI::instance(); 00443 00444 $searchEngineString = 'ezsearch'; 00445 if ( $ini->hasVariable( 'SearchSettings', 'SearchEngine' ) == true ) 00446 { 00447 $searchEngineString = $ini->variable( 'SearchSettings', 'SearchEngine' ); 00448 } 00449 00450 $directoryList = array(); 00451 if ( $ini->hasVariable( 'SearchSettings', 'ExtensionDirectories' ) ) 00452 { 00453 $extensionDirectories = $ini->variable( 'SearchSettings', 'ExtensionDirectories' ); 00454 if ( is_array( $extensionDirectories ) ) 00455 { 00456 $directoryList = eZExtension::expandedPathList( $extensionDirectories, 'search/plugins' ); 00457 } 00458 } 00459 00460 $kernelDir = array( 'kernel/search/plugins' ); 00461 $directoryList = array_merge( $kernelDir, $directoryList ); 00462 00463 foreach( $directoryList as $directory ) 00464 { 00465 $searchEngineFile = implode( '/', array( $directory, strtolower( $searchEngineString ), strtolower( $searchEngineString ) ) ) . '.php'; 00466 00467 if ( file_exists( $searchEngineFile ) ) 00468 { 00469 eZDebugSetting::writeDebug( 'kernel-search-ezsearch', 'Loading search engine from ' . $searchEngineFile, 'eZSearch::getEngine' ); 00470 00471 include_once( $searchEngineFile ); 00472 $GLOBALS[$instanceName] = new $searchEngineString(); 00473 return $GLOBALS[$instanceName]; 00474 } 00475 } 00476 00477 eZDebug::writeDebug( 'Unable to find the search engine:' . $searchEngineString, 'eZSearch' ); 00478 eZDebug::writeDebug( 'Tried paths: ' . implode( ', ', $directoryList ), 'eZSearch' ); 00479 return false; 00480 } 00481 00482 /** 00483 * Notifies search engine about the change of section of a set of objects 00484 * 00485 * @since 4.6 00486 * @param array $objectIDs 00487 * @param int $sectionID 00488 * @return false|mixed false in case method is undefined, otherwise return the result of the search engine call 00489 */ 00490 public static function updateObjectsSection( array $objectIDs, $sectionID ) 00491 { 00492 $searchEngine = eZSearch::getEngine(); 00493 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'updateObjectsSection' ) ) 00494 { 00495 return $searchEngine->updateObjectsSection( $objectIDs, $sectionID ); 00496 } 00497 return false; 00498 } 00499 00500 /** 00501 * Notifies search engine about section changes 00502 * 00503 * @since 4.1 00504 * @param int $nodeID 00505 * @param int $sectionID 00506 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00507 */ 00508 public static function updateNodeSection( $nodeID, $sectionID ) 00509 { 00510 $searchEngine = eZSearch::getEngine(); 00511 00512 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'updateNodeSection' ) ) 00513 { 00514 return $searchEngine->updateNodeSection( $nodeID, $sectionID ); 00515 } 00516 00517 return false; 00518 } 00519 00520 /** 00521 * Notifies search engine about node visibility changes 00522 * 00523 * @since 4.1 00524 * @param int $nodeID 00525 * @param string $action "hide" or "show" 00526 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00527 */ 00528 public static function updateNodeVisibility( $nodeID, $action ) 00529 { 00530 $searchEngine = eZSearch::getEngine(); 00531 00532 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'updateNodeVisibility' ) ) 00533 { 00534 return $searchEngine->updateNodeVisibility( $nodeID, $action ); 00535 } 00536 00537 return false; 00538 } 00539 00540 /** 00541 * Notifies search engine about new node assignments added 00542 * 00543 * @since 4.1 00544 * @param int $mainNodeID 00545 * @param int $objectID 00546 * @param array $nodeAssignmentIDList 00547 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00548 */ 00549 public static function addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList ) 00550 { 00551 $searchEngine = eZSearch::getEngine(); 00552 00553 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'addNodeAssignment' ) ) 00554 { 00555 return $searchEngine->addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList ); 00556 } 00557 00558 return false; 00559 } 00560 00561 /** 00562 * Notifies search engine about removed node assignments and what the new main node is (same if not changed) 00563 * 00564 * @since 4.1 00565 * @param int $mainNodeID 00566 * @param int $newMainNodeID 00567 * @param int $objectID 00568 * @param array $nodeAssigmentIDList 00569 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00570 */ 00571 public static function removeNodeAssignment( $mainNodeID, $newMainNodeID, $objectID, $nodeAssigmentIDList ) 00572 { 00573 $searchEngine = eZSearch::getEngine(); 00574 00575 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'removeNodeAssignment' ) ) 00576 { 00577 return $searchEngine->removeNodeAssignment( $mainNodeID, $newMainNodeID, $objectID, $nodeAssigmentIDList ); 00578 } 00579 00580 return false; 00581 } 00582 00583 /** 00584 * Notifies search engine about nodes being removed 00585 * 00586 * @since 4.1 00587 * @param array $nodeIdList Array of node ID to remove. 00588 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00589 */ 00590 public static function removeNodes( array $nodeIdList ) 00591 { 00592 $searchEngine = self::getEngine(); 00593 00594 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'removeNodes' ) ) 00595 { 00596 return $searchEngine->removeNodes( $nodeIdList ); 00597 } 00598 00599 return false; 00600 } 00601 00602 /** 00603 * Notifies search engine about updates to object states 00604 * 00605 * @since 4.1 00606 * @param int $objectID 00607 * @param array $objectStateList 00608 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00609 */ 00610 public static function updateObjectState( $objectID, $objectStateList ) 00611 { 00612 $searchEngine = eZSearch::getEngine(); 00613 00614 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'updateObjectState' ) ) 00615 { 00616 return $searchEngine->updateObjectState( $objectID, $objectStateList ); 00617 } 00618 00619 return false; 00620 } 00621 00622 /** 00623 * Notifies search engine about an swap node operation 00624 * 00625 * @since 4.1 00626 * @param int $nodeID 00627 * @param int $selectedNodeID 00628 * @param array $nodeIdList 00629 * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call 00630 */ 00631 public static function swapNode( $nodeID, $selectedNodeID, $nodeIdList = array() ) 00632 { 00633 $searchEngine = eZSearch::getEngine(); 00634 00635 if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'swapNode' ) ) 00636 { 00637 return $searchEngine->swapNode( $nodeID, $selectedNodeID, $nodeIdList = array() ); 00638 } 00639 00640 return false; 00641 } 00642 } 00643 00644 ?>