From b334f17af5468923c93bad566f4e343378986569 Mon Sep 17 00:00:00 2001 From: lsces Date: Wed, 27 Aug 2025 17:22:06 +0100 Subject: Code updated to PHP8.4 and namespace --- admin/admin_search_inc.php | 71 ++++---- admin/schema_inc.php | 56 +++--- admin/upgrade_inc.php | 72 -------- bit_setup_inc.php | 30 ---- cmd_line_reindex.php | 11 +- directory_search.php | 46 ++--- includes/bit_setup_inc.php | 39 +++++ includes/classes/SearchLib.php | 341 ++++++++++++++++++++++++++++++++++++ includes/classes/SearchStatsLib.php | 57 ++++++ includes/refresh.php | 63 +++++++ includes/refresh_functions.php | 188 ++++++++++++++++++++ index.php | 47 ++--- modules/mod_ajax_search.tpl | 6 +- modules/mod_global_search.php | 10 +- modules/mod_global_search.tpl | 7 +- modules/mod_package_search.php | 12 +- refresh.php | 66 ------- refresh_functions.php | 191 -------------------- search_lib.php | 340 ----------------------------------- searchstats_lib.php | 56 ------ stats.php | 36 ++-- templates/admin_search.tpl | 4 +- templates/global_mini_search.tpl | 2 +- templates/menu_search.tpl | 2 +- templates/search.tpl | 4 +- 25 files changed, 826 insertions(+), 931 deletions(-) delete mode 100644 admin/upgrade_inc.php delete mode 100644 bit_setup_inc.php create mode 100755 includes/bit_setup_inc.php create mode 100755 includes/classes/SearchLib.php create mode 100755 includes/classes/SearchStatsLib.php create mode 100755 includes/refresh.php create mode 100755 includes/refresh_functions.php delete mode 100644 refresh.php delete mode 100644 refresh_functions.php delete mode 100644 search_lib.php delete mode 100644 searchstats_lib.php diff --git a/admin/admin_search_inc.php b/admin/admin_search_inc.php index d383c82..5bee3c7 100644 --- a/admin/admin_search_inc.php +++ b/admin/admin_search_inc.php @@ -1,4 +1,6 @@ array( +$formSearchToggles = [ + 'search_stats' => [ 'label' => 'Search Statistics', 'note' => 'Record searches made and their frequency.', // 'page' => 'SearchStats', - ), - 'search_index_on_submit' => array( + ], + 'search_index_on_submit' => [ 'label' => 'Index On Submit', 'note' => 'Index articles, blogs and wiki pages immdiately on submission. If unchecked, pages will be updated randomly according the the refresh rate below.', - ), -); + ], +]; -$formSearchInts = array( - 'search_refresh_rate' => array( +$formSearchInts = [ + 'search_refresh_rate' => [ 'label' => 'Search Refresh Rate', 'note' => 'Varies the rate at which updates to the search index are made, 1 = every page read, while rate>1 will introduce a random chance of a refresh every "rate" pages', - ), - 'search_min_wordlength' => array( + ], + 'search_min_wordlength' => [ 'label' => 'Minimum number of letters for search words', 'note' => 'By settings this value to 3, you can ignore search words such as "a" or "or", however searches for a number like "13" will be ignored as well.', - ), - 'search_max_syllwords' => array( + ], + 'search_max_syllwords' => [ 'label' => 'Maximum number of words', 'note' => 'The maximum number of words containing a syllable that can be serached for in any one search.', - ), - 'search_syll_age' => array( + ], + 'search_syll_age' => [ 'label' => 'Age in hours of search cache', 'note' => 'Define the Maximum age of cached search results for any given syllable. The results cache will be used to provide a search result if it is available, and will be cleared after either the age, or when the results cache reaches it\'s limit', - ), - 'search_lru_purge_rate' => array( + ], + 'search_lru_purge_rate' => [ 'label' => 'Least Recently Used (LRU) list purging rate', 'note' => 'Purge the results cache every "rate" pages. This will keep space available in the cache for new search results', - ), - 'search_lru_length' => array( + ], + 'search_lru_length' => [ 'label' => 'Least Recently Used (LRU) list length', 'note' => 'Limit the results cache to this number of entries', - ), -); + ], +]; if( !empty( $_REQUEST['del_index'] ) ) { - require_once( SEARCH_PKG_PATH.'/refresh_functions.php' ); + require_once SEARCH_PKG_INCLUDE_PATH.'/refresh_functions.php'; delete_index_content_type( $_REQUEST["where"] ); - $feedback['success'] = tra( "The search index was successfully deleted." ); + $feedback['success'] = KernelTools::tra( "The search index was successfully deleted." ); } if( !empty( $_REQUEST['del_index_reindex'] ) ) { - require_once( SEARCH_PKG_PATH.'/refresh_functions.php' ); + require_once SEARCH_PKG_INCLUDE_PATH.'/refresh_functions.php'; $count = rebuild_index( $_REQUEST["where"] ); - $feedback['success'] = tra( "The search index was successfully deleted." ).tra( "Number of items re-indexed" ).": ".$count; + $feedback['success'] = KernelTools::tra( "The search index was successfully deleted." ).KernelTools::tra( "Number of items re-indexed" ).": ".$count; } if( !empty( $_REQUEST['del_searchwords'] ) ) { - require_once( SEARCH_PKG_PATH.'/refresh_functions.php' ); + require_once SEARCH_PKG_INCLUDE_PATH.'/refresh_functions.php'; delete_search_words_and_syllables(); - $feedback['success'] = tra( "The searchwords were successfully purged from the database." ); + $feedback['success'] = KernelTools::tra( "The searchwords were successfully purged from the database." ); } if( !empty( $_REQUEST['store_prefs'] ) ) { @@ -82,12 +84,12 @@ $gBitSmarty->assign( 'formSearchToggles', $formSearchToggles ); $gBitSmarty->assign( 'formSearchInts', $formSearchInts ); $gBitSmarty->assign( 'feedback', $feedback ); -$formSearchTypeToggles = array( - 'search_restrict_types' => array( +$formSearchTypeToggles = [ + 'search_restrict_types' => [ 'label' => 'Restrict Types', - 'note' => 'If selected the search will be limited to those selected below.' - ), -); + 'note' => 'If selected the search will be limited to those selected below.', + ], +]; $gBitSmarty->assign( 'formSearchTypeToggles', $formSearchTypeToggles ); // allow selection of what packages can have search @@ -100,7 +102,7 @@ if( !empty( $_REQUEST['store_content'] ) ) { simple_set_toggle( $item, SEARCH_PKG_NAME ); } foreach( array_keys( $formSearchable['guids'] ) as $searchable ) { - $gBitSystem->storeConfig( $searchable, ( ( !empty( $_REQUEST['searchable_content'] ) && in_array( $searchable, $_REQUEST['searchable_content'] ) ) ? 'y' : NULL ), SEARCH_PKG_NAME ); + $gBitSystem->storeConfig( $searchable, !empty( $_REQUEST['searchable_content'] ) && in_array( $searchable, $_REQUEST['searchable_content'] ) ? 'y' : null, SEARCH_PKG_NAME ); } } @@ -115,7 +117,7 @@ $gBitSmarty->assign( 'formSearchable', $formSearchable ); /* usually done in mod_package_search.php - but the module can be not here the first time */ if( empty( $contentTypes ) ) { - $contentTypes = array( '' => tra( 'All Content' ) ); + $contentTypes = [ '' => KernelTools::tra( 'All Content' ) ]; foreach( $gLibertySystem->mContentTypes as $cType ) { if( $gBitSystem->getConfig( 'search_pkg_'.$cType['content_type_guid']) ) { $contentTypes[$cType['content_type_guid']] = $gLibertySystem->getContentTypeName( $cType['content_type_guid'] ); @@ -123,4 +125,3 @@ if( empty( $contentTypes ) ) { } $gBitSmarty->assign( 'contentTypes', $contentTypes ); } -?> diff --git a/admin/schema_inc.php b/admin/schema_inc.php index 8d26111..55a4522 100644 --- a/admin/schema_inc.php +++ b/admin/schema_inc.php @@ -1,6 +1,6 @@ " searchword C(80) PRIMARY, @@ -25,7 +25,7 @@ $tables = array( hits I4 " -) ; +] ; global $gBitInstaller; @@ -34,44 +34,44 @@ foreach( array_keys( $tables ) AS $tableName ) { $gBitInstaller->registerSchemaTable( SEARCH_PKG_NAME, $tableName, $tables[$tableName] ); } -$indices = array ( - 'searchidx_last_update_idx' => array( 'table' => 'search_index', 'cols' => 'last_update', 'opts' => NULL ), - 'searchidx_word_idx' => array( 'table' => 'search_index', 'cols' => 'searchword', 'opts' => NULL ), - 'searchidx_con_idx' => array( 'table' => 'search_index', 'cols' => 'content_id', 'opts' => NULL ), - 'searchsyl_last_used_idx' => array( 'table' => 'search_syllable', 'cols' => 'last_used', 'opts' => NULL ) -); +$indices = [ + 'searchidx_last_update_idx' => [ 'table' => 'search_index', 'cols' => 'last_update', 'opts' => null ], + 'searchidx_word_idx' => [ 'table' => 'search_index', 'cols' => 'searchword', 'opts' => null ], + 'searchidx_con_idx' => [ 'table' => 'search_index', 'cols' => 'content_id', 'opts' => null ], + 'searchsyl_last_used_idx' => [ 'table' => 'search_syllable', 'cols' => 'last_used', 'opts' => null ] +]; $gBitInstaller->registerSchemaIndexes( SEARCH_PKG_NAME, $indices ); -$gBitInstaller->registerPackageInfo( SEARCH_PKG_NAME, array( +$gBitInstaller->registerPackageInfo( SEARCH_PKG_NAME, [ 'description' => "This package makes any content on your site searchable.", 'license' => 'LGPL', -) ); +] ); // ### Default Preferences -// array(SEARCH_PKG_NAME, 'search_fulltext','y'), -$gBitInstaller->registerPreferences( SEARCH_PKG_NAME, array( - array(SEARCH_PKG_NAME, 'search_stats','n'), - array(SEARCH_PKG_NAME, 'search_index_on_submit','n'), - array(SEARCH_PKG_NAME, 'search_refresh_rate','5'), - array(SEARCH_PKG_NAME, 'search_min_wordlength','3'), - array(SEARCH_PKG_NAME, 'search_max_syllwords','100'), - array(SEARCH_PKG_NAME, 'search_lru_purge_rate','5'), - array(SEARCH_PKG_NAME, 'search_lru_length','100'), - array(SEARCH_PKG_NAME, 'search_syll_age','48') -) ); - -$moduleHash = array( - 'mod_package_search' => array( +// [ SEARCH_PKG_NAME, 'search_fulltext','y' ], +$gBitInstaller->registerPreferences( SEARCH_PKG_NAME, [ + [ SEARCH_PKG_NAME, 'search_stats','n' ], + [ SEARCH_PKG_NAME, 'search_index_on_submit','n' ], + [ SEARCH_PKG_NAME, 'search_refresh_rate','5' ], + [ SEARCH_PKG_NAME, 'search_min_wordlength','3' ], + [ SEARCH_PKG_NAME, 'search_max_syllwords','100' ], + [ SEARCH_PKG_NAME, 'search_lru_purge_rate','5' ], + [ SEARCH_PKG_NAME, 'search_lru_length','100' ], + [ SEARCH_PKG_NAME, 'search_syll_age','48' ] +] ); + +$moduleHash = [ + 'mod_package_search' => [ 'title' => 'Search', 'ord' => 3, 'pos' => 'r', 'module_rsrc' => 'bitpackage:search/mod_package_search.tpl' -) ); +] ]; $gBitInstaller->registerModules( $moduleHash ); // Requirements -$gBitInstaller->registerRequirements( SEARCH_PKG_NAME, array( - 'liberty' => array( 'min' => '2.1.4' ), -)); +$gBitInstaller->registerRequirements( SEARCH_PKG_NAME, [ + 'liberty' => [ 'min' => '5.0.0' ], +] ); diff --git a/admin/upgrade_inc.php b/admin/upgrade_inc.php deleted file mode 100644 index 3ceef25..0000000 --- a/admin/upgrade_inc.php +++ /dev/null @@ -1,72 +0,0 @@ - array( - 'BWR2' => array( -array( 'DATADICT' => array( - array( 'RENAMETABLE' => array( - 'tiki_searchindex' => 'search_index', - 'tiki_searchsyllable' => 'search_syllable', - 'tiki_search_stats' => 'search_stats', - 'tiki_searchwords' => 'search_words', - )), - array( 'RENAMECOLUMN' => array( - 'search_index' => array( '`count`' => '`i_count` I4' ), - )), - array( 'DROPCOLUMN' => array( - 'search_index' => array( '`location`' ), - )), -)), - ) -), - -'BONNIE' => array( - 'BWR1' => array( -// STEP 1 - Data is transient, so let's recreate the table with proper multi-column keys -array( 'DATADICT' => array( - array( 'DROPTABLE' => array( - 'tiki_searchindex' - )), - array( 'CREATE' => array ( - 'tiki_searchindex' => " - searchword C(80) PRIMARY, - location C(80) PRIMARY, - content_id I4 PRIMARY, - count I4 NOTNULL default '1', - last_update I4 NOTNULL - ", - )), -)), - -// STEP 2 -array( 'DATADICT' => array( - array( 'RENAMECOLUMN' => array( - 'tiki_searchsyllable' => array( '`lastUsed`' => '`last_used` I8', - '`lastUpdated`' => '`last_updated` I8' ), - )), -)), - -// STEP 3 -array( 'DATADICT' => array( - array( 'CREATEINDEX' => array( - 'tiki_searchidx_con_id_idx' => array( 'tiki_searchindex', '`content_id`', array() ), - 'tiki_searchidx_word_idx' => array( 'tiki_searchindex', '`searchword`', array() ), - 'tiki_searchidx_loc_idx' => array( 'tiki_searchindex', '`location`', array() ), - 'tiki_searchidx_update_idx' => array( 'tiki_searchindex', '`last_update`', array() ), - )), -)), - - ) -) - -); - -if( isset( $upgrades[$gUpgradeFrom][$gUpgradeTo] ) ) { - $gBitSystem->registerUpgrade( SEARCH_PKG_NAME, $upgrades[$gUpgradeFrom][$gUpgradeTo] ); -} - - -?> diff --git a/bit_setup_inc.php b/bit_setup_inc.php deleted file mode 100644 index 5efdf16..0000000 --- a/bit_setup_inc.php +++ /dev/null @@ -1,30 +0,0 @@ - 'search', - 'package_path' => dirname( __FILE__ ).'/', - 'service' => LIBERTY_SERVICE_SEARCH, -); -$gBitSystem->registerPackage( $registerHash ); - -if( $gBitSystem->isPackageActive( 'search' ) ) { - $menuHash = array( - 'package_name' => SEARCH_PKG_NAME, - 'index_url' => SEARCH_PKG_URL.'index.php', - 'menu_template' => 'bitpackage:search/menu_search.tpl', - ); - $gBitSystem->registerAppMenu( $menuHash ); - - // ********** SEARCH ************ - // Register the search refresh function - // But only if the Index On Submit isn't set - if( ! $gBitSystem->isFeatureActive("search_index_on_submit") ) { - include_once( SEARCH_PKG_PATH.'refresh.php' ); - register_shutdown_function("refresh_search_index"); - } - include_once( SEARCH_PKG_PATH.'refresh_functions.php' ); - $gLibertySystem->registerService( LIBERTY_SERVICE_SEARCH, SEARCH_PKG_NAME, - array('content_store_function' => 'refresh_index')); -} -?> diff --git a/cmd_line_reindex.php b/cmd_line_reindex.php index 2ff439a..648879c 100644 --- a/cmd_line_reindex.php +++ b/cmd_line_reindex.php @@ -42,11 +42,11 @@ $_SERVER['HTTP_HOST'] = 'batch'; $_SERVER['HTTP_USER_AGENT'] = 'batch'; $_SERVER['SCRIPT_URL'] = 'batch'; $_SERVER['SERVER_SOFTWARE'] = 'batch'; -$HTTP_SERVER_VARS['HTTP_USER_AGENT'] = 'batch'; +$_SERVER['HTTP_USER_AGENT'] = 'batch'; -require_once( '../kernel/setup_inc.php' ); -require_once( LIBERTY_PKG_PATH.'LibertyBase.php'); -require_once( SEARCH_PKG_PATH.'refresh_functions.php'); +require_once '../kernel/includes/setup_inc.php'; +use Bitweaver\Liberty\LibertyBase; +require_once SEARCH_PKG_INCLUDES_PATH.'refresh_functions.php'; $whatToIndex = "pages"; $unindexedOnly = false; @@ -86,6 +86,5 @@ if (isset($argc)) { // we are running from the command line. function microtime_float() { list($usec, $sec) = explode(" ", microtime()); - return ((float)$usec + (float)$sec); + return (float) $usec + (float) $sec; } -?> diff --git a/directory_search.php b/directory_search.php index 319312e..19f2b88 100644 --- a/directory_search.php +++ b/directory_search.php @@ -17,9 +17,9 @@ /** * required setup */ -require_once( '../kernel/setup_inc.php' ); +require_once '../kernel/includes/setup_inc.php'; -include_once( DIRECTORY_PKG_PATH.'dir_lib.php' ); +include_once DIRECTORY_PKG_PATH.'dir_lib.php'; $gBitSystem->verifyFeature( 'feature_directory' ); $gBitSystem->verifyPermission( 'bit_p_view_directory' ); @@ -28,40 +28,28 @@ $gBitSmarty->assign('words', $_REQUEST['words']); $gBitSmarty->assign('where', $_REQUEST['where']); $gBitSmarty->assign('how', $_REQUEST['how']); -if ( empty( $_REQUEST["sort_mode"] ) ) { - $sort_mode = 'hits_desc'; -} else { - $sort_mode = $_REQUEST["sort_mode"]; -} -$gBitSmarty->assignByRef('sort_mode', $sort_mode); +$sort_mode = $_REQUEST["sort_mode"] ?? 'hits_desc'; +$gBitSmarty->assign('sort_mode', $sort_mode); + +$offset = $_REQUEST["offset"] ?? 0; -if (!isset($_REQUEST["offset"])) { - $offset = 0; -} else { - $offset = $_REQUEST["offset"]; -} if (isset($_REQUEST['page'])) { $page = &$_REQUEST['page']; $offset = ($page - 1) * $max_records; } -$gBitSmarty->assignByRef('offset', $offset); +$gBitSmarty->assign('offset', $offset); + +$find = $_REQUEST["find"] ?? ''; -if (isset($_REQUEST["find"])) { - $find = $_REQUEST["find"]; -} else { - $find = ''; -} $gBitSmarty->assign('find', $find); -if ($_REQUEST['where'] == 'all') { - $items = $dirlib->dir_search($_REQUEST['words'], $_REQUEST['how'], $offset, $max_records, $sort_mode); -} else { - $items = $dirlib->dir_search_cat($_REQUEST['parent'], $_REQUEST['words'], $_REQUEST['how'], $offset, $max_records, $sort_mode); -} +$items = $_REQUEST['where'] == 'all' + ? $dirlib->dir_search($_REQUEST['words'], $_REQUEST['how'], $offset, $max_records, $sort_mode) + : $dirlib->dir_search_cat($_REQUEST['parent'], $_REQUEST['words'], $_REQUEST['how'], $offset, $max_records, $sort_mode); $cant_pages = ceil($items["cant"] / $max_records); -$gBitSmarty->assignByRef('cant_pages', $cant_pages); -$gBitSmarty->assign('actual_page', 1 + ($offset / $max_records)); +$gBitSmarty->assign('cant_pages', $cant_pages); +$gBitSmarty->assign('actual_page', 1 + $offset / $max_records); if ($items["cant"] > ($offset + $max_records)) { $gBitSmarty->assign('next_offset', $offset + $max_records); @@ -75,10 +63,8 @@ if ($offset > 0) { $gBitSmarty->assign('prev_offset', -1); } -$gBitSmarty->assignByRef('items', $items["data"]); +$gBitSmarty->assign('items', $items["data"]); $section = 'directory'; // Display the template -$gBitSystem->display( 'bitpackage:search/directory_search.tpl', NULL, array( 'display_mode' => 'display' )); - -?> +$gBitSystem->display( 'bitpackage:search/directory_search.tpl', null, array( 'display_mode' => 'display' )); diff --git a/includes/bit_setup_inc.php b/includes/bit_setup_inc.php new file mode 100755 index 0000000..554f3ae --- /dev/null +++ b/includes/bit_setup_inc.php @@ -0,0 +1,39 @@ + 'search', + 'package_path' => dirname( dirname( __FILE__ ) ).'/', + 'service' => LIBERTY_SERVICE_SEARCH, +]; + +// fix to quieten down VS Code which can't see the dynamic creation of these ... +define( 'SEARCH_PKG_NAME', $pRegisterHash['package_name'] ); +define( 'SEARCH_PKG_URL', BIT_ROOT_URL . basename( $pRegisterHash['package_path'] ) . '/' ); +define( 'SEARCH_PKG_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/' ); +define( 'SEARCH_PKG_INCLUDE_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/includes/'); +define( 'SEARCH_PKG_CLASS_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/includes/classes/'); +define( 'SEARCH_PKG_ADMIN_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/admin/'); + +$gBitSystem->registerPackage( $pRegisterHash ); + +if( $gBitSystem->isPackageActive( 'search' ) ) { + $menuHash = [ + 'package_name' => SEARCH_PKG_NAME, + 'index_url' => SEARCH_PKG_URL.'index.php', + 'menu_template' => 'bitpackage:search/menu_search.tpl', + ]; + $gBitSystem->registerAppMenu( $menuHash ); + + // ********** SEARCH ************ + // Register the search refresh function + // But only if the Index On Submit isn't set + if( ! $gBitSystem->isFeatureActive("search_index_on_submit") ) { + include_once SEARCH_PKG_INCLUDE_PATH . 'refresh.php'; + register_shutdown_function("refresh_search_index"); + } + include_once SEARCH_PKG_INCLUDE_PATH . 'refresh_functions.php'; + $gLibertySystem->registerService( LIBERTY_SERVICE_SEARCH, SEARCH_PKG_NAME, + [ 'content_store_function' => 'refresh_index'] ); +} \ No newline at end of file diff --git a/includes/classes/SearchLib.php b/includes/classes/SearchLib.php new file mode 100755 index 0000000..024d340 --- /dev/null +++ b/includes/classes/SearchLib.php @@ -0,0 +1,341 @@ +wordlist_cache = []; // for caching queries to the LRU-cache-list. + } + + public function register_search($words) { + $words = strtolower($words); + $words = addslashes($words); + $words = preg_split("/\s/", $words); + foreach ($words as $word) { + $word = trim($word); + $cant = $this->mDb->getOne("SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . + "search_stats` WHERE `term`=?", [ $word ]); + $query = $cant + ? "UPDATE `" . BIT_DB_PREFIX . "search_stats` SET `hits`= `hits` + 1 WHERE `term`=?" + : "INSERT INTO `" . BIT_DB_PREFIX . "search_stats` (`term`,`hits`) VALUES (?,1)"; + $result = $this->mDb->query($query, [ $word ]); + } + } + + public function find( &$pParamHash ) { // $where, $words, $offset, $max_records, $plUsePart = false) { + $pParamHash['words'] = preg_split("/[\W]+/", strtolower($pParamHash['words']), -1, PREG_SPLIT_NO_EMPTY); + if ( isset($pParamHash['$plUsePart']) && $pParamHash['$plUsePart'] ) { + $wordList = $this->get_wordlist_from_syllables( $pParamHash['words'] ); + if ([ $wordList ] ) { + $pParamHash['words'] = array_merge( $pParamHash['words'], $wordList ); + } + } + $res = $this->find_exact_generic( $pParamHash ); + return $res; + } + + /* + * This function checks the search_syllable table to see how old the "syllable" is + * If the syllable is to old or doesn't exist, it refreshes the syllable/word list stored in search_words + * Then, it get a list of words from the search_words table and returns an array of them + */ + public function get_wordlist_from_syllables($syllables) { + global $gBitSystem; + $search_syll_age = $gBitSystem->getConfig( 'search_syll_age', SEARCH_PKG_NAME ); + $ret = []; + foreach($syllables as $syllable) { + $bindvars = [ $syllable ]; + $age = time() - $this->mDb->getOne( + "select `last_updated` from `" . BIT_DB_PREFIX . "search_syllable` where `syllable`=?", + $bindvars); + if(!$age || $age > ($search_syll_age * 3600)) {// older than search_syll_age hours + $a = $this->refresh_lru_wordlist($syllable); + } + $lruList = $this->get_lru_wordlist($syllable); + if (is_array($lruList)) { + $ret = array_merge($ret, $lruList); + } + // update lru last used value (Used to purge oldest last used records) + $now = time(); + $this->mDb->query("update `" . BIT_DB_PREFIX . "search_syllable` set `last_used`=? where `syllable`=?", + [ (int) $now, $syllable ]); + } + return $ret; + } + + public function get_lru_wordlist($syllable) { + $ret = []; + if(!isset($this->wordlist_cache[$syllable])) { + $query = "select `searchword` from `" . BIT_DB_PREFIX . "search_words` where `syllable`=?"; + $result = $this->mDb->query($query, [ $syllable ]); + if ($result->RecordCount() > 0) { + while ($res = $result->fetchRow()) { + $this->wordlist_cache[$syllable][]=$res["searchword"]; + } + $ret = $this->wordlist_cache[$syllable]; + } + } + return $ret; + } + + public function refresh_lru_wordlist($syllable) { + global $gBitSystem; + $search_max_syllwords = $gBitSystem->getConfig( 'search_max_syllwords', SEARCH_PKG_NAME );; + $search_lru_length = $gBitSystem->getConfig( 'search_lru_length', SEARCH_PKG_NAME );; + $search_lru_purge_rate = $gBitSystem->getConfig( 'search_lru_purge_rate', SEARCH_PKG_NAME ); + $ret = []; + + // delete from wordlist and lru list + $this->mDb->query("delete from `".BIT_DB_PREFIX."search_words` where `syllable`=?", [ $syllable ],-1,-1); + $this->mDb->query("delete from `".BIT_DB_PREFIX."search_syllable` where `syllable`=?", [ $syllable ],-1,-1); + if (!isset($search_max_syllwords)) { + $search_max_syllwords = 100; + } + $query = "SELECT `searchword`, SUM(`i_count`) AS `cnt` FROM `" . BIT_DB_PREFIX . + "search_index` WHERE `searchword` LIKE ? GROUP BY `searchword` ORDER BY 2 desc"; + $result = $this->mDb->query($query, [ "%$syllable%" ], $search_max_syllwords); // search_max_syllwords: how many different search_words that contain the syllable are taken into account?. Sortet by number of occurences. + while ($res = $result->fetchRow()) { + $ret[] = $res["searchword"]; + } + // cache this long running query + foreach($ret as $searchword) { + $this->mDb->query("INSERT INTO `" . BIT_DB_PREFIX . + "search_words` (`syllable`,`searchword`) VALUES (?,?)", + [ $syllable, $searchword ], -1, -1); + } + // set lru list parameters + $now = time(); + $this->mDb->query("INSERT INTO `" . BIT_DB_PREFIX . + "search_syllable`(`syllable`,`last_used`,`last_updated`) values (?,?,?)", + [ $syllable, (int) $now, (int) $now ]); + + // at random rate: check length of lru list and purge these that + // have not been used for long time. This is what a lru list + // basically does + list($usec, $sec) = explode(" ", microtime()); + srand (ceil($sec + 100 * $usec)); + if(rand(1, $search_lru_purge_rate) == 1) { + $lrulength = $this->mDb->getOne("SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . + "search_syllable`", []); + if ($lrulength > $search_lru_length) { // only purge if lru list is too long. + //purge oldest + $oldwords = []; + $diff = $lrulength - $search_lru_length; + $query = "select `syllable` from `".BIT_DB_PREFIX."search_syllable` ORDER BY `last_used` asc"; + $result = $this->mDb->query($query, [], $diff); + while ($res = $result->fetchRow()) { + $oldwords[]=$res["syllable"]; + } + foreach($oldwords as $oldword) { + $this->mDb->query("delete from `" . BIT_DB_PREFIX . + "search_words` where `syllable`=?", [ $oldword ], -1, -1); + $this->mDb->query("delete from `" . BIT_DB_PREFIX . + "search_syllable` where `syllable`=?", [ $oldword ], -1, -1); + } + + } + } + return $ret; + } + + public function find_with_or($allowed, $selectSql, $joinSql, $whereSql, $bindVars,&$pParamHash) { + // Putting in the below hack because mssql cannot select distinct on a text blob column. + $qPlaceHolders1 = implode(',', array_fill(0, count($pParamHash['words']), '?')); + $bindVars = array_merge( $pParamHash['words'], $allowed ); +// $this->getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); + $ret = []; + $query = "SELECT + lc.`content_id`, + lc.`title`, + lc.`format_guid`, + lc.`content_type_guid`, + COALESCE(lch.`hits`,0) AS hits, + lc.`created`, + lc.`last_modified`, + lc.`data`, + COALESCE(( + SELECT SUM(i_count) + FROM `" . BIT_DB_PREFIX . "search_index` si + WHERE si.`content_id`=lc.`content_id` AND si.`searchword` IN (" . $qPlaceHolders1 . ") + ),0) AS relevancy + $selectSql + FROM `" . BIT_DB_PREFIX . "liberty_content` lc + LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) + $joinSql + WHERE ( + SELECT SUM(i_count) + FROM `" . BIT_DB_PREFIX . "search_index` si + WHERE si.`content_id`=lc.`content_id` + AND si.`searchword` IN (" . $qPlaceHolders1 . ") + GROUP BY + si.`content_id` + )>0 $whereSql + ORDER BY 9 DESC, 5 DESC + "; + $querycant = "SELECT + COUNT(*) + FROM `" . BIT_DB_PREFIX . "liberty_content` lc + LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) + $joinSql + WHERE ( + SELECT SUM(i_count) + FROM `" . BIT_DB_PREFIX . "search_index` si + WHERE si.`content_id`=lc.`content_id` + AND si.`searchword` IN (" . $qPlaceHolders1 . ") + GROUP BY + si.`content_id` + )>0 $whereSql"; + $result = $this->mDb->query( $query, array_merge( $pParamHash['words'] ,$bindVars), $pParamHash['max_records'], $pParamHash['offset'] ); + $pParamHash['cant'] = $this->mDb->getOne( $querycant, $bindVars ); + while ($res = $result->fetchRow()) { + $res['href'] = BIT_ROOT_URL . "index.php?content_id=" . $res['content_id']; + $ret[] = $res; + } + return $ret; + } + + public function find_with_and($allowed, $selectSql, $joinSql, $whereSql, $bindVars, &$pParamHash) { + // Make a slot for the search word. + $bindVars[0] = null; + $bindVars = array_merge( $bindVars, $allowed ); +// LibertyContent::getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); + + $ret = []; + $first = true; + foreach($pParamHash['words'] as $word) { + $query = "SELECT lc.`content_id` AS hash_key, + lc.`content_id`, + lc.`title`, + lc.`format_guid`, + lc.`content_type_guid`, + COALESCE(lch.`hits`,0) AS hits, + lc.`created`, + lc.`last_modified`, + lc.`data`, + si.`i_count` AS relevancy + $selectSql + FROM `" . BIT_DB_PREFIX . "liberty_content` lc + LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) + $joinSql + INNER JOIN `".BIT_DB_PREFIX."search_index` si ON (si.`content_id`=lc.`content_id` AND si.`searchword` = ? ) + WHERE `i_count` > 0 $whereSql + ORDER BY 9 DESC, 5 DESC + "; + $bindVars[0] = $word; + $result = $this->mDb->getAssoc( $query, $bindVars ); + if ($first) { + $ret = $result; + $first = false; + } + else { + $this->mergeResults($ret, $result); + } + } + /* count it */ + $pParamHash['cant'] = count($ret); + + /* Sort it */ + uasort($ret, 'search_relevance_sort'); + + /* slice it */ + $ret = array_slice($ret, $pParamHash['offset'], $pParamHash['offset'] + $pParamHash['max_records']); + + /* Set the hrefs. */ + foreach ($ret as $content_id => $data) { + $ret[$content_id]['href'] = BIT_ROOT_URL . "index.php?content_id=" . $data['content_id']; + } + + return $ret; + } + + public function find_exact_generic( &$pParamHash ) { + global $gPage, $gBitSystem, $gLibertySystem, $gBitDbType; + $allowed = []; + $ret = []; + foreach( $gLibertySystem->mContentTypes as $contentType ) { + if (( $pParamHash['content_type_guid'] == $contentType["content_type_guid"] or $pParamHash['content_type_guid'] == "" ) // pages ? + and $this->has_permission($contentType["content_type_guid"]) + and ( ! $gBitSystem->getConfig('search_restrict_types') || + $gBitSystem->getConfig('search_pkg_'.$contentType["content_type_guid"]) ) ) { + $allowed[] = $contentType["content_type_guid"]; + } + } + + if (count($allowed) > 0 && count($pParamHash['words']) > 0) { + $selectSql = ''; + $joinSql = ''; + $whereSql = " AND lc.`content_type_guid` IN (" . implode(',', array_fill(0, count($allowed), '?')) . ") "; + $bindVars = []; + + $ret = isset($pParamHash['useAnd']) && $pParamHash['useAnd'] + ? $this->find_with_and($allowed, $selectSql, $joinSql, $whereSql, $bindVars, $pParamHash) + : $this->find_with_or($allowed, $selectSql, $joinSql, $whereSql, $bindVars, $pParamHash); + } else { + $pParamHash['cant'] = 0; + $ret = []; + } + return $ret; + } + + public function mergeResults(&$ret, $result) { + // Remove those that don't overlap or update relevance + foreach ($ret as $content_id => $data) { + if (!isset($result[$content_id])) { + unset($ret[$content_id]); + } + else { + $ret[$content_id]['relevancy'] += $result[$content_id]['relevancy']; + } + } + } + + public static function has_permission($pContentType = null) { + global $gBitUser, $gLibertySystem; + + if ( ! empty( $pContentType ) ) { + $object = LibertyBase::getLibertyObject(1, $pContentType, false); + if ( ! empty( $object ) ) { + // Note that we can't do verify access here because + // we are using a generic object but we can at least get a + // basic permission check here. + return $object->hasViewPermission(false); + } + } + + return false; + } + +} # class SearchLib + +if (!defined('search_relevance_sort')) { + function search_relevance_sort($a, $b) { + $rel = $b['relevancy'] - $a['relevancy']; + if ($rel == 0) { + $rel = $b['hits'] - $a['hits']; + } + return $rel; + } +} \ No newline at end of file diff --git a/includes/classes/SearchStatsLib.php b/includes/classes/SearchStatsLib.php new file mode 100755 index 0000000..de5bd9e --- /dev/null +++ b/includes/classes/SearchStatsLib.php @@ -0,0 +1,57 @@ +mDb->query($query,[]); + } + + function list_search_stats($offset, $max_records, $sort_mode, $find) { + + if ($find) { + $mid = " WHERE (UPPER(`term`) LIKE ?)"; + $bindvars = [ "%".strtoupper( $find )."%" ]; + } else { + $mid = ""; + $bindvars = []; + } + + $query = "SELECT * FROM `".BIT_DB_PREFIX."search_stats` $mid ORDER BY ".$this->mDb->convertSortmode($sort_mode); + $query_cant = "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."search_stats` $mid"; + $result = $this->mDb->query($query,$bindvars,$max_records,$offset); + $cant = $this->mDb->getOne($query_cant,$bindvars); + $ret = []; + + while ($res = $result->fetchRow()) { + $ret[] = $res; + } + + $retval = []; + $retval["data"] = $ret; + $retval["cant"] = $cant; + return $retval; + } +} + +$searchstatslib = new SearchStatsLib(); diff --git a/includes/refresh.php b/includes/refresh.php new file mode 100755 index 0000000..7b6796d --- /dev/null +++ b/includes/refresh.php @@ -0,0 +1,63 @@ +isPackageActive( 'wiki' ) ) { + // if wiki is active, let's always refresh + random_refresh_index("wiki"); + } +// if( $gBitSystem->isPackageActive( 'articles' ) ) { +// $locs[''] = ARTICLES_PKG_NAME; +// } + if( $gBitSystem->isPackageActive( 'blogs' ) ) { + // if blogs is active, let's always refresh + random_refresh_index("blogs"); + $locs['random_refresh_index']="blog_posts"; + } + + // comments can be everywhere? + $locs['random_refresh_index'] = "comments"; + // some refreshes to enhance the refreshing stats + $locs['refresh_index_oldest'] = ""; + $key = array_rand( $locs ); + // random refresh + + // hack around php database driver issues when a different database from bitweaver is accessed elsewhere during page render + // this happens in the phpBB package when phpBB is in a different db from bitweaver in MySQL + // This only works on some databases + global $gBitSystem, $gBitDbName; + $gBitSystem->mDb->mDb->SelectDB( $gBitDbName ); + + if ( !empty ($key) ) + call_user_func( $key, $locs[$key] ); + } +} diff --git a/includes/refresh_functions.php b/includes/refresh_functions.php new file mode 100755 index 0000000..50dfec7 --- /dev/null +++ b/includes/refresh_functions.php @@ -0,0 +1,188 @@ +mDb) ) { + $cant = $gBitSystem->mDb->getOne("SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . $table . "`", []); + if($cant > 0) { + $query = "SELECT `content_id` FROM `" . BIT_DB_PREFIX . $table . "`"; + $contentId = $gBitSystem->mDb->getOne($query, [], 1, rand(0, $cant - 1)); + refresh_index($contentId); + } + } +} + +/* + * Index Refresh Function for Liberty Content + * This can be called directly to force a refresh for a particular piece of tiki content. + * This is also called by the Random_Refresh_* indexing functions from tiki. + * This currently works for wiki pages, blog posts and articles. + */ + +function refresh_index( $pContentObject = null ) { + global $gBitSystem; + if (is_object($pContentObject)) { + if ( (!isset($pContentObject->mInfo["index_data"])) and method_exists($pContentObject, 'setIndexData')) { + $pContentObject->setIndexData() ; + } + if (isset($pContentObject->mInfo["index_data"]) and isset($pContentObject->mContentId)) { + if (isset($pContentObject->mType["content_type_guid"])) { + $contentTypeGuid = $pContentObject->mType["content_type_guid"]; + } elseif (isset($pContentObject->mContentTypeGuid)) { + $contentTypeGuid = $pContentObject->mContentTypeGuid; + } + if (isset($contentTypeGuid)) { + $words = prepare_words($pContentObject->mInfo["index_data"]); + insert_index($words, $contentTypeGuid, $pContentObject->mContentId); + } + } + } +} + +function refresh_index_oldest(){ + global $gBitSystem; + $contentId = $gBitSystem->mDb->getOne("SELECT `content_id` FROM `" . BIT_DB_PREFIX . + "search_index` ORDER BY `last_update`", []); + if ( isset($contentId) ) { + refresh_index($contentId); + } +} + +function prepare_words($data) { + $data = strip_tags($data); + // split into words + $sstrings = preg_split("/[\W]+/", $data, -1, PREG_SPLIT_NO_EMPTY); + // count words + $words = []; + foreach ($sstrings as $key=>$value) { + if(!isset($words[strtolower($value)])) { + $words[strtolower($value)] = 0; + } + $words[strtolower($value)]++; + } + return $words; +} + +function delete_index ($pContentId) { + global $gBitSystem; + if( !empty( $pContentId ) ) { + $sql = "DELETE FROM `".BIT_DB_PREFIX."search_index` WHERE `content_id`=?"; + $gBitSystem->mDb->query($sql, [ $pContentId ]); + } +} + +function insert_index( &$words, $location, $pContentId ) { + global $gBitSystem; + if( !empty( $pContentId ) ) { + delete_index($pContentId); + $now = $gBitSystem->getUTCTime(); + foreach ($words as $key=>$value) { + if (strlen($key) >= $gBitSystem->getConfig( 'search_min_wordlength') ) { + // todo: stopwords + common words. + $query = "INSERT INTO `" . BIT_DB_PREFIX . "search_index` + (`content_id`,`searchword`,`i_count`,`last_update`) values (?,?,?,?)"; + $gBitSystem->mDb->query($query, [ $pContentId, $key, (int) $value, $now ]); + } // What happened to location? + } + } +} + +function delete_search_words_and_syllables() { + global $gBitSystem; + $gBitSystem->mDb->query( "DELETE FROM `" . BIT_DB_PREFIX . "search_words`", [] ); + $gBitSystem->mDb->query( "DELETE FROM `" . BIT_DB_PREFIX . "search_syllable`", [] ); +} + +function delete_index_content_type($pContentType) { + global $gBitSystem; + $sql = "DELETE FROM `" . BIT_DB_PREFIX . "search_index`"; + $array = []; + if ( $pContentType <> "pages" ) { + $sql .= " WHERE `content_id` IN (SELECT `content_id` FROM `" . BIT_DB_PREFIX . + "liberty_content` where `content_type_guid` = ?)"; + $array = [ $pContentType ]; + } + $gBitSystem->mDb->query( $sql, $array ); +} + +function rebuild_index($pContentType, $pUnindexedOnly = false) { + global $gBitSystem, $gLibertySystem; + $arguments = []; + $whereClause = ""; + ini_set("max_execution_time", "3000"); + if (!$pUnindexedOnly) { + delete_index_content_type($pContentType); + } + $query = "SELECT `content_id`, `content_type_guid` FROM `" . BIT_DB_PREFIX . "liberty_content`"; + if( !empty( $pContentType ) && $pContentType != "pages" ) { + $whereClause = " WHERE `content_type_guid` = ?"; + $arguments[] = $pContentType; + } + + if( $pUnindexedOnly ) { + if (empty($whereClause)) { + $whereClause = " WHERE "; + } else { + $whereClause .= " AND "; + } + $whereClause .= "`content_id` NOT IN (SELECT DISTINCT `content_id` FROM `" . BIT_DB_PREFIX . "search_index`)" ; + } + + $orderBy = " ORDER BY `content_type_guid` "; + $result = $gBitSystem->mDb->query( $query.$whereClause.$orderBy, $arguments ); + $count = 0; + if( $result ) { + $count = $result->RecordCount(); + while ($res = $result->fetchRow()) { + if( isset( $gLibertySystem->mContentTypes[$res["content_type_guid"]] ) ) { + $type = $gLibertySystem->mContentTypes[$res["content_type_guid"]]; + require_once constant( strtoupper( $type['handler_package'] ) . '_PKG_PATH' ) . $type['handler_file']; + $obj = new $type['handler_class']( null, $res["content_id"] ); + refresh_index($obj); + unset($obj); + } + } + } + return $count; +} diff --git a/index.php b/index.php index 1208904..eb384bf 100644 --- a/index.php +++ b/index.php @@ -13,9 +13,11 @@ /** * Initialization */ -require_once( '../kernel/setup_inc.php' ); +require_once '../kernel/includes/setup_inc.php'; -require_once( SEARCH_PKG_PATH.'/search_lib.php'); +use Bitweaver\Search\SearchLib; +use Bitweaver\Liberty\LibertyContent; +use Bitweaver\KernelTools; $searchlib = new SearchLib(); @@ -24,7 +26,7 @@ $gBitSystem->verifyPackage( 'search' ); // contentType list created in mod_package_search.php at present // but this is left in case a different search option is used if( empty( $contentTypes ) ) { - $contentTypes = array( '' => tra( 'All Content' ) ); + $contentTypes = [ '' => KernelTools::tra( 'All Content' ) ]; foreach( $gLibertySystem->mContentTypes as $cType ) { $contentTypes[$cType['content_type_guid']] = $gLibertySystem->getContentTypeName( $cType['content_type_guid'] ); } @@ -36,7 +38,7 @@ if( !empty($_REQUEST["highlight"]) ) { $_REQUEST["words"]=$_REQUEST["highlight"]; } else { // a nice big, groovy search will be cool to have one day... - $gBitSystem->display( 'bitpackage:search/search.tpl', 'Search', array( 'display_mode' => 'display' )); + $gBitSystem->display( 'bitpackage:search/search.tpl', 'Search', [ 'display_mode' => 'display' ]); die; } @@ -53,32 +55,21 @@ if (!isset($_REQUEST["content_type_guid"])) { LibertyContent::prepGetList($_REQUEST); -if( isset( $_REQUEST['usePart'] ) && $_REQUEST['usePart']=='on' ) { - $_REQUEST['usePart']=true; -} else { - $_REQUEST['usePart']=false; -} +$_REQUEST['usePart'] = isset( $_REQUEST['usePart'] ) && $_REQUEST['usePart']=='on' ? true : false; $gBitSmarty->assign('usePart', $_REQUEST['usePart']); $gBitSmarty->assign('searchType', $_REQUEST['usePart'] ? "Using Partial Word Search" : "Using Exact Word Search"); -if( isset( $_REQUEST['useAnd'] ) && $_REQUEST['useAnd']=='on' ) { - $_REQUEST['useAnd']=true; -} else { - $_REQUEST['useAnd']=false; -} +$_REQUEST['useAnd'] = isset( $_REQUEST['useAnd'] ) && $_REQUEST['useAnd']=='on' ? true : false; $gBitSmarty->assign('useAnd', $_REQUEST['useAnd']); // Build the query using words -if ((!isset($_REQUEST["words"])) || (empty($_REQUEST["words"]))) { - $_REQUEST["words"] = ''; -} else { - $_REQUEST["words"] = strip_tags($_REQUEST["words"]); -} +$_REQUEST["words"] = !isset($_REQUEST["words"]) || (empty($_REQUEST["words"])) ? '' : strip_tags($_REQUEST["words"]); + $gBitSmarty->assign('words', $_REQUEST["words"]); $results = $searchlib->find( $_REQUEST ); if ($_REQUEST['cant'] <> 1) $where2 .= "s"; -$gBitSmarty->assign('where2', tra($where2)); +$gBitSmarty->assign('where2', KernelTools::tra($where2)); $gBitSmarty->assign('content_type_guid', $_REQUEST["content_type_guid"]); $stubContent = new LibertyContent(); @@ -86,26 +77,22 @@ if ( $_REQUEST['cant'] > 0 ) { foreach( array_keys( $results ) as $k ) { if( empty( $results[$k]['title'] ) ) { $date_format = $gBitSystem->get_long_date_format(); - if( $gBitSystem->mServerTimestamp->get_display_offset() ) { - $date_format = preg_replace( "/ ?%Z/", "", $date_format ); - } else { - $date_format = preg_replace( "/%Z/", "UTC", $date_format ); - } + $date_format = $gBitSystem->mServerTimestamp->get_display_offset() + ? preg_replace( "/ ?%Z/", "", $date_format ) + : preg_replace( "/%Z/", "UTC", $date_format ); $date_string = $gBitSystem->mServerTimestamp->getDisplayDateFromUTC( $results[$k]['created'] ); $results[$k]['title'] = $gBitSystem->mServerTimestamp->strftime( $date_format, $date_string, true ); } if( !empty( $results[$k]['data'] ) ) { - $results[$k]['parsed'] = $stubContent->parseData( $results[$k] ); + $results[$k]['parsed'] = $stubContent->parseDataHash( $results[$k] ); } } } LibertyContent::postGetList( $_REQUEST ); -$gBitSmarty->assignByRef( 'listInfo', $_REQUEST['listInfo'] ); +$gBitSmarty->assign( 'listInfo', $_REQUEST['listInfo'] ); // Find search results (build array) -$gBitSmarty->assignByRef('results', $results); +$gBitSmarty->assign('results', $results); // Display the template $gBitSystem->display( 'bitpackage:search/search.tpl', 'Search Results for: '.strip_tags($_REQUEST["highlight"]), array( 'display_mode' => 'display' )); - -?> diff --git a/modules/mod_ajax_search.tpl b/modules/mod_ajax_search.tpl index 4375f6a..5ab1a4b 100644 --- a/modules/mod_ajax_search.tpl +++ b/modules/mod_ajax_search.tpl @@ -1,7 +1,7 @@ {* this needs to go in , but we don't have a way of doing that from a module yet. *} - - - + + {* end of section *} diff --git a/modules/mod_global_search.php b/modules/mod_global_search.php index f658299..5e8c51c 100644 --- a/modules/mod_global_search.php +++ b/modules/mod_global_search.php @@ -17,11 +17,12 @@ /** * Initialization */ -global $gLibertySystem; -require_once(SEARCH_PKG_PATH."search_lib.php"); +global $gLibertySystem; +use Bitweaver\Search\SearchLib; +use Bitweaver\KernelTools; if( empty( $contentTypes ) ) { - $contentTypes = array( '' => tra( 'All Content' ) ); + $contentTypes = [ '' => KernelTools::tra( 'All Content' ) ]; foreach( $gLibertySystem->mContentTypes as $cType ) { if (SearchLib::has_permission($cType["content_type_guid"]) and ( ! $gBitSystem->getConfig('search_restrict_types') || @@ -30,5 +31,4 @@ if( empty( $contentTypes ) ) { } } } -$_template->tpl_vars['contentTypes'] = new Smarty_variable( $contentTypes ); -?> +$gBitSmarty->assign( 'contentTypes', $contentTypes ); diff --git a/modules/mod_global_search.tpl b/modules/mod_global_search.tpl index 455a82e..15a7659 100644 --- a/modules/mod_global_search.tpl +++ b/modules/mod_global_search.tpl @@ -1,7 +1,10 @@ -{* $Header$ *} - +{strip} +{if empty($moduleTitle)} + {assign var=moduleTitle value=""} +{/if} {if $gBitSystem->isPackageActive( 'search' )} {bitmodule title="$moduleTitle" name="search_new"} {include file="bitpackage:search/global_mini_search.tpl"} {/bitmodule} {/if} +{/strip} \ No newline at end of file diff --git a/modules/mod_package_search.php b/modules/mod_package_search.php index 071d475..925fc66 100644 --- a/modules/mod_package_search.php +++ b/modules/mod_package_search.php @@ -14,16 +14,17 @@ * @subpackage modules */ +use Bitweaver\Search\SearchLib; +use Bitweaver\KernelTools; + /** * Initialization */ -require_once(SEARCH_PKG_PATH."search_lib.php"); - + global $gBitSystem, $gLibertySystem; + $tplName = $gBitSystem->getActivePackage().'_mini_search.tpl'; $searchTemplatePath = BIT_ROOT_URL.constant( strtoupper( $gBitSystem->getActivePackage() ).'_PKG_PATH' ).'templates/'.$tplName; - global $gLibertySystem; - if( file_exists( $searchTemplatePath ) ) { $searchTemplateRsrc = 'bitpackage:'.$gBitSystem->getActivePackage().'/'.$tplName; $searchTitle = ucfirst( $gBitSystem->getActivePackage() ); @@ -33,7 +34,7 @@ require_once(SEARCH_PKG_PATH."search_lib.php"); } if( empty( $contentTypes ) ) { - $contentTypes = array( '' => tra( 'All Content' ) ); + $contentTypes = [ '' => KernelTools::tra( 'All Content' ) ]; foreach( $gLibertySystem->mContentTypes as $cType ) { if (SearchLib::has_permission($cType["content_type_guid"]) and ( ! $gBitSystem->getConfig('search_restrict_types') || @@ -46,4 +47,3 @@ require_once(SEARCH_PKG_PATH."search_lib.php"); $gBitSmarty->assign( 'searchTitle', $searchTitle ); $gBitSmarty->assign( 'miniSearchRsrc', $searchTemplateRsrc ); -?> diff --git a/refresh.php b/refresh.php deleted file mode 100644 index 14e7cec..0000000 --- a/refresh.php +++ /dev/null @@ -1,66 +0,0 @@ -isPackageActive( 'wiki' ) ) { - // if wiki is active, let's always refresh - random_refresh_index("wiki"); - } - if( $gBitSystem->isPackageActive( 'articles' ) ) { - $locs[''] = ARTICLES_PKG_NAME; - } - if( $gBitSystem->isPackageActive( 'blogs' ) ) { - // if blogs is active, let's always refresh - random_refresh_index("blogs"); - $locs['random_refresh_index']="blog_posts"; - } - - // comments can be everywhere? - $locs['random_refresh_index'] = "comments"; - // some refreshes to enhance the refreshing stats - $locs['refresh_index_oldest'] = ""; - $key = array_rand( $locs ); - // random refresh - - // hack around php database driver issues when a different database from bitweaver is accessed elsewhere during page render - // this happens in the phpBB package when phpBB is in a different db from bitweaver in MySQL - // This only works on some databases - global $gBitSystem, $gBitDbName; - $gBitSystem->mDb->mDb->SelectDB( $gBitDbName ); - - if ( !empty ($key) ) - call_user_func( $key, $locs[$key] ); - } -} - -?> diff --git a/refresh_functions.php b/refresh_functions.php deleted file mode 100644 index c0f12ac..0000000 --- a/refresh_functions.php +++ /dev/null @@ -1,191 +0,0 @@ -mDb->getOne("SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . $table . "`", array()); - if($cant > 0) { - $query = "SELECT `content_id` FROM `" . BIT_DB_PREFIX . $table . "`"; - $contentId = $gBitSystem->mDb->getOne($query, array(), 1, rand(0, $cant - 1)); - refresh_index($contentId); - } - } -} - -/* - * Index Refresh Function for Liberty Content - * This can be called directly to force a refresh for a particular piece of tiki content. - * This is also called by the Random_Refresh_* indexing functions from tiki. - * This currently works for wiki pages, blog posts and articles. - */ - -function refresh_index( $pContentObject = null ) { - global $gBitSystem; - if (is_object($pContentObject)) { - if ( (!isset($pContentObject->mInfo["index_data"])) and method_exists($pContentObject, 'setIndexData')) { - $pContentObject->setIndexData() ; - } - if (isset($pContentObject->mInfo["index_data"]) and isset($pContentObject->mContentId)) { - if (isset($pContentObject->mType["content_type_guid"])) { - $contentTypeGuid = $pContentObject->mType["content_type_guid"]; - } elseif (isset($pContentObject->mContentTypeGuid)) { - $contentTypeGuid = $pContentObject->mContentTypeGuid; - } - if (isset($contentTypeGuid)) { - $words = prepare_words($pContentObject->mInfo["index_data"]); - insert_index($words, $contentTypeGuid, $pContentObject->mContentId); - } - } - } -} - -function refresh_index_oldest(){ - global $gBitSystem; - $contentId = $gBitSystem->mDb->getOne("SELECT `content_id` FROM `" . BIT_DB_PREFIX . - "search_index` ORDER BY `last_update`", array()); - if ( isset($contentId) ) { - refresh_index($contentId); - } -} - -function prepare_words($data) { - $data = strip_tags($data); - // split into words - $sstrings = preg_split("/[\W]+/", $data, -1, PREG_SPLIT_NO_EMPTY); - // count words - $words = array(); - foreach ($sstrings as $key=>$value) { - if(!isset($words[strtolower($value)])) { - $words[strtolower($value)] = 0; - } - $words[strtolower($value)]++; - } - return($words); -} - -function delete_index ($pContentId) { - global $gBitSystem; - if( !empty( $pContentId ) ) { - $sql = "DELETE FROM `".BIT_DB_PREFIX."search_index` WHERE `content_id`=?"; - $gBitSystem->mDb->query($sql, array($pContentId)); - } -} - -function insert_index( &$words, $location, $pContentId ) { - global $gBitSystem; - if( !empty( $pContentId ) ) { - delete_index($pContentId); - $now = $gBitSystem->getUTCTime(); - foreach ($words as $key=>$value) { - if (strlen($key) >= $gBitSystem->getConfig( 'search_min_wordlength') ) { - // todo: stopwords + common words. - $query = "INSERT INTO `" . BIT_DB_PREFIX . "search_index` - (`content_id`,`searchword`,`i_count`,`last_update`) values (?,?,?,?)"; - $gBitSystem->mDb->query($query, array($pContentId, $key, (int) $value, $now)); - } // What happened to location? - } - } -} - -function delete_search_words_and_syllables() { - global $gBitSystem; - $gBitSystem->mDb->query( "DELETE FROM `" . BIT_DB_PREFIX . "search_words`", array() ); - $gBitSystem->mDb->query( "DELETE FROM `" . BIT_DB_PREFIX . "search_syllable`", array() ); -} - -function delete_index_content_type($pContentType) { - global $gBitSystem; - $sql = "DELETE FROM `" . BIT_DB_PREFIX . "search_index`"; - $array = array(); - if ( $pContentType <> "pages" ) { - $sql .= " WHERE `content_id` IN (SELECT `content_id` FROM `" . BIT_DB_PREFIX . - "liberty_content` where `content_type_guid` = ?)"; - $array = array($pContentType); - } - $gBitSystem->mDb->query( $sql, $array ); -} - -function rebuild_index($pContentType, $pUnindexedOnly = false) { - global $gBitSystem, $gLibertySystem; - $arguments = array(); - $whereClause = ""; - ini_set("max_execution_time", "3000"); - if (!$pUnindexedOnly) { - delete_index_content_type($pContentType); - } - $query = "SELECT `content_id`, `content_type_guid` FROM `" . BIT_DB_PREFIX . "liberty_content`"; - if( !empty( $pContentType ) && $pContentType != "pages" ) { - $whereClause = " WHERE `content_type_guid` = ?"; - $arguments[] = $pContentType; - } - - if( $pUnindexedOnly ) { - if (empty($whereClause)) { - $whereClause = " WHERE "; - } else { - $whereClause .= " AND "; - } - $whereClause .= "`content_id` NOT IN (SELECT DISTINCT `content_id` FROM `" . BIT_DB_PREFIX . "search_index`)" ; - } - - $orderBy = " ORDER BY `content_type_guid` "; - $result = $gBitSystem->mDb->query( $query.$whereClause.$orderBy, $arguments ); - $count = 0; - if( $result ) { - $count = $result->RecordCount(); - while ($res = $result->fetchRow()) { - if( isset( $gLibertySystem->mContentTypes[$res["content_type_guid"]] ) ) { - $type = $gLibertySystem->mContentTypes[$res["content_type_guid"]]; - require_once( constant( strtoupper( $type['handler_package'] ).'_PKG_PATH' ).$type['handler_file'] ); - $obj = new $type['handler_class']( NULL, $res["content_id"] ); - refresh_index($obj); - unset($obj); - } - } - } - return $count; -} -?> diff --git a/search_lib.php b/search_lib.php deleted file mode 100644 index e593351..0000000 --- a/search_lib.php +++ /dev/null @@ -1,340 +0,0 @@ -wordlist_cache = array(); // for caching queries to the LRU-cache-list. - } - - function register_search($words) { - $words = strtolower($words); - $words = addslashes($words); - $words = preg_split("/\s/", $words); - foreach ($words as $word) { - $word = trim($word); - $cant = $this->mDb->getOne("SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . - "search_stats` WHERE `term`=?", array($word)); - if ($cant) { - $query = "UPDATE `" . BIT_DB_PREFIX . "search_stats` SET `hits`= `hits` + 1 WHERE `term`=?"; - } else { - $query = "INSERT INTO `" . BIT_DB_PREFIX . "search_stats` (`term`,`hits`) VALUES (?,1)"; - } - $result = $this->mDb->query($query,array($word)); - } - } - - function find( &$pParamHash ) { // $where, $words, $offset, $max_records, $plUsePart = false) { - $pParamHash['words'] = preg_split("/[\W]+/", strtolower($pParamHash['words']), -1, PREG_SPLIT_NO_EMPTY); - if ( isset($pParamHash['$plUsePart']) && $pParamHash['$plUsePart'] ) { - $wordList = $this->get_wordlist_from_syllables( $pParamHash['words'] ); - if ( array( $wordList ) ) { - $pParamHash['words'] = array_merge( $pParamHash['words'], $wordList ); - } - } - $res = $this->find_exact_generic( $pParamHash ); - return $res; - } - - /* - * This function checks the search_syllable table to see how old the "syllable" is - * If the syllable is to old or doesn't exist, it refreshes the syllable/word list stored in search_words - * Then, it get a list of words from the search_words table and returns an array of them - */ - function get_wordlist_from_syllables($syllables) { - global $gBitSystem; - $search_syll_age = $gBitSystem->getConfig( 'search_syll_age', SEARCH_PKG_NAME ); - $ret = array(); - foreach($syllables as $syllable) { - $bindvars = array($syllable); - $age = time() - $this->mDb->getOne( - "select `last_updated` from `" . BIT_DB_PREFIX . "search_syllable` where `syllable`=?", - $bindvars); - if(!$age || $age > ($search_syll_age * 3600)) {// older than search_syll_age hours - $a = $this->refresh_lru_wordlist($syllable); - } - $lruList = $this->get_lru_wordlist($syllable); - if (is_array($lruList)) { - $ret = array_merge($ret, $lruList); - } - // update lru last used value (Used to purge oldest last used records) - $now = time(); - $this->mDb->query("update `" . BIT_DB_PREFIX . "search_syllable` set `last_used`=? where `syllable`=?", - array((int) $now, $syllable)); - } - return $ret; - } - - function get_lru_wordlist($syllable) { - $ret = array(); - if(!isset($this->wordlist_cache[$syllable])) { - $query = "select `searchword` from `" . BIT_DB_PREFIX . "search_words` where `syllable`=?"; - $result = $this->mDb->query($query, array($syllable)); - if ($result->RecordCount() > 0) { - while ($res = $result->fetchRow()) { - $this->wordlist_cache[$syllable][]=$res["searchword"]; - } - $ret = $this->wordlist_cache[$syllable]; - } - } - return $ret; - } - - function refresh_lru_wordlist($syllable) { - global $gBitSystem; - $search_max_syllwords = $gBitSystem->getConfig( 'search_max_syllwords', SEARCH_PKG_NAME );; - $search_lru_length = $gBitSystem->getConfig( 'search_lru_length', SEARCH_PKG_NAME );; - $search_lru_purge_rate = $gBitSystem->getConfig( 'search_lru_purge_rate', SEARCH_PKG_NAME ); - $ret = array(); - - // delete from wordlist and lru list - $this->mDb->query("delete from `".BIT_DB_PREFIX."search_words` where `syllable`=?",array($syllable),-1,-1); - $this->mDb->query("delete from `".BIT_DB_PREFIX."search_syllable` where `syllable`=?",array($syllable),-1,-1); - if (!isset($search_max_syllwords)) { - $search_max_syllwords = 100; - } - $query = "SELECT `searchword`, SUM(`i_count`) AS `cnt` FROM `" . BIT_DB_PREFIX . - "search_index` WHERE `searchword` LIKE ? GROUP BY `searchword` ORDER BY 2 desc"; - $result = $this->mDb->query($query, array('%' . $syllable . '%'), $search_max_syllwords); // search_max_syllwords: how many different search_words that contain the syllable are taken into account?. Sortet by number of occurences. - while ($res = $result->fetchRow()) { - $ret[] = $res["searchword"]; - } - // cache this long running query - foreach($ret as $searchword) { - $this->mDb->query("INSERT INTO `" . BIT_DB_PREFIX . - "search_words` (`syllable`,`searchword`) VALUES (?,?)", - array($syllable, $searchword), -1, -1); - } - // set lru list parameters - $now = time(); - $this->mDb->query("INSERT INTO `" . BIT_DB_PREFIX . - "search_syllable`(`syllable`,`last_used`,`last_updated`) values (?,?,?)", - array($syllable,(int) $now,(int) $now)); - - // at random rate: check length of lru list and purge these that - // have not been used for long time. This is what a lru list - // basically does - list($usec, $sec) = explode(" ", microtime()); - srand (ceil($sec + 100 * $usec)); - if(rand(1, $search_lru_purge_rate) == 1) { - $lrulength = $this->mDb->getOne("SELECT COUNT(*) FROM `" . BIT_DB_PREFIX . - "search_syllable`", array()); - if ($lrulength > $search_lru_length) { // only purge if lru list is too long. - //purge oldest - $oldwords = array(); - $diff = $lrulength - $search_lru_length; - $query = "select `syllable` from `".BIT_DB_PREFIX."search_syllable` ORDER BY `last_used` asc"; - $result = $this->mDb->query($query, array(), $diff); - while ($res = $result->fetchRow()) { - $oldwords[]=$res["syllable"]; - } - foreach($oldwords as $oldword) { - $this->mDb->query("delete from `" . BIT_DB_PREFIX . - "search_words` where `syllable`=?", array($oldword), -1, -1); - $this->mDb->query("delete from `" . BIT_DB_PREFIX . - "search_syllable` where `syllable`=?", array($oldword), -1, -1); - } - - } - } - return $ret; - } - - function find_with_or($allowed, $selectSql, $joinSql, $whereSql, $bindVars,&$pParamHash) { - // Putting in the below hack because mssql cannot select distinct on a text blob column. - $qPlaceHolders1 = implode(',', array_fill(0, count($pParamHash['words']), '?')); - $bindVars = array_merge( $pParamHash['words'], $allowed ); - LibertyContent::getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); - $ret = array(); - $query = "SELECT - lc.`content_id`, - lc.`title`, - lc.`format_guid`, - lc.`content_type_guid`, - COALESCE(lch.`hits`,0) AS hits, - lc.`created`, - lc.`last_modified`, - lc.`data`, - COALESCE(( - SELECT SUM(i_count) - FROM `" . BIT_DB_PREFIX . "search_index` si - WHERE si.`content_id`=lc.`content_id` AND si.`searchword` IN (" . $qPlaceHolders1 . ") - ),0) AS relevancy - $selectSql - FROM `" . BIT_DB_PREFIX . "liberty_content` lc - LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) - $joinSql - WHERE ( - SELECT SUM(i_count) - FROM `" . BIT_DB_PREFIX . "search_index` si - WHERE si.`content_id`=lc.`content_id` - AND si.`searchword` IN (" . $qPlaceHolders1 . ") - GROUP BY - si.`content_id` - )>0 $whereSql - ORDER BY 9 DESC, 5 DESC - "; - $querycant = "SELECT - COUNT(*) - FROM `" . BIT_DB_PREFIX . "liberty_content` lc - LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) - $joinSql - WHERE ( - SELECT SUM(i_count) - FROM `" . BIT_DB_PREFIX . "search_index` si - WHERE si.`content_id`=lc.`content_id` - AND si.`searchword` IN (" . $qPlaceHolders1 . ") - GROUP BY - si.`content_id` - )>0 $whereSql"; - $result = $this->mDb->query( $query, array_merge( $pParamHash['words'] ,$bindVars), $pParamHash['max_records'], $pParamHash['offset'] ); - $pParamHash['cant'] = $this->mDb->getOne( $querycant, $bindVars ); - while ($res = $result->fetchRow()) { - $res['href'] = BIT_ROOT_URL . "index.php?content_id=" . $res['content_id']; - $ret[] = $res; - } - return $ret; - } - - function find_with_and($allowed, $selectSql, $joinSql, $whereSql, $bindVars, &$pParamHash) { - // Make a slot for the search word. - $bindVars[0] = NULL; - $bindVars = array_merge( $bindVars, $allowed ); - LibertyContent::getServicesSql( 'content_list_sql_function', $selectSql, $joinSql, $whereSql, $bindVars ); - - $ret = array(); - $first = true; - foreach($pParamHash['words'] as $word) { - $query = "SELECT lc.`content_id` AS hash_key, - lc.`content_id`, - lc.`title`, - lc.`format_guid`, - lc.`content_type_guid`, - COALESCE(lch.`hits`,0) AS hits, - lc.`created`, - lc.`last_modified`, - lc.`data`, - si.`i_count` AS relevancy - $selectSql - FROM `" . BIT_DB_PREFIX . "liberty_content` lc - LEFT OUTER JOIN `".BIT_DB_PREFIX."liberty_content_hits` lch ON (lc.`content_id` = lch.`content_id`) - $joinSql - INNER JOIN `".BIT_DB_PREFIX."search_index` si ON (si.`content_id`=lc.`content_id` AND si.`searchword` = ? ) - WHERE `i_count` > 0 $whereSql - ORDER BY 9 DESC, 5 DESC - "; - $bindVars[0] = $word; - $result = $this->mDb->getAssoc( $query, $bindVars ); - if ($first) { - $ret = $result; - $first = false; - } - else { - $this->mergeResults($ret, $result); - } - } - /* count it */ - $pParamHash['cant'] = count($ret); - - /* Sort it */ - uasort($ret, 'search_relevance_sort'); - - /* slice it */ - $ret = array_slice($ret, $pParamHash['offset'], $pParamHash['offset'] + $pParamHash['max_records']); - - /* Set the hrefs. */ - foreach ($ret as $content_id => $data) { - $ret[$content_id]['href'] = BIT_ROOT_URL . "index.php?content_id=" . $data['content_id']; - } - - return $ret; - } - - function find_exact_generic( &$pParamHash ) { - global $gPage, $gBitSystem, $gLibertySystem, $gBitDbType; - $allowed = array(); - $ret = array(); - foreach( $gLibertySystem->mContentTypes as $contentType ) { - if (( $pParamHash['content_type_guid'] == $contentType["content_type_guid"] or $pParamHash['content_type_guid'] == "" ) // pages ? - and $this->has_permission($contentType["content_type_guid"]) - and ( ! $gBitSystem->getConfig('search_restrict_types') || - $gBitSystem->getConfig('search_pkg_'.$contentType["content_type_guid"]) ) ) { - $allowed[] = $contentType["content_type_guid"]; - } - } - - if (count($allowed) > 0 && count($pParamHash['words']) > 0) { - $selectSql = ''; - $joinSql = ''; - $whereSql = " AND lc.`content_type_guid` IN (" . implode(',', array_fill(0, count($allowed), '?')) . ") "; - $bindVars = array(); - - if (isset($pParamHash['useAnd']) && $pParamHash['useAnd']) { - return $this->find_with_and($allowed, $selectSql, $joinSql, $whereSql, $bindVars, $pParamHash); - } - else { - return $this->find_with_or($allowed, $selectSql, $joinSql, $whereSql, $bindVars, $pParamHash); - } - } else { - $pParamHash['cant'] = 0; - return array(); - } - } - - function mergeResults(&$ret, $result) { - // Remove those that don't overlap or update relevance - foreach ($ret as $content_id => $data) { - if (!isset($result[$content_id])) { - unset($ret[$content_id]); - } - else { - $ret[$content_id]['relevancy'] += $result[$content_id]['relevancy']; - } - } - } - - public static function has_permission($pContentType = NULL) { - global $gBitUser, $gLibertySystem; - - if ( ! empty( $pContentType ) ) { - $object = LibertyBase::getLibertyObject(1, $pContentType, FALSE); - if ( ! empty( $object ) ) { - // Note that we can't do verify access here because - // we are using a generic object but we can at least get a - // basic permission check here. - return $object->hasViewPermission(FALSE); - } - } - - return FALSE; - } - -} # class SearchLib - -if (!defined('search_relevance_sort')) { - function search_relevance_sort($a, $b) { - $rel = $b['relevancy'] - $a['relevancy']; - if ($rel == 0) { - $rel = $b['hits'] - $a['hits']; - } - return $rel; - } -} - -?> diff --git a/searchstats_lib.php b/searchstats_lib.php deleted file mode 100644 index 2a23f50..0000000 --- a/searchstats_lib.php +++ /dev/null @@ -1,56 +0,0 @@ -mDb->query($query,array()); - } - - function list_search_stats($offset, $max_records, $sort_mode, $find) { - - if ($find) { - $mid = " WHERE (UPPER(`term`) LIKE ?)"; - $bindvars = array("%".strtoupper( $find )."%"); - } else { - $mid = ""; - $bindvars = array(); - } - - $query = "SELECT * FROM `".BIT_DB_PREFIX."search_stats` $mid ORDER BY ".$this->mDb->convertSortmode($sort_mode); - $query_cant = "SELECT COUNT(*) FROM `".BIT_DB_PREFIX."search_stats` $mid"; - $result = $this->mDb->query($query,$bindvars,$max_records,$offset); - $cant = $this->mDb->getOne($query_cant,$bindvars); - $ret = array(); - - while ($res = $result->fetchRow()) { - $ret[] = $res; - } - - $retval = array(); - $retval["data"] = $ret; - $retval["cant"] = $cant; - return $retval; - } -} - -$searchstatslib = new SearchStatsLib(); - -?> diff --git a/stats.php b/stats.php index 5f75804..047c56f 100644 --- a/stats.php +++ b/stats.php @@ -17,9 +17,9 @@ /** * requires setup */ -require_once( '../kernel/setup_inc.php' ); +require_once '../kernel/includes/setup_inc.php'; -include_once( SEARCH_PKG_PATH.'searchstats_lib.php'); +use Bitweaver\Search\SearchStatsLib; $gBitSystem->verifyFeature( 'search_stats' ); $gBitSystem->verifyPermission( 'p_admin' ); @@ -28,37 +28,25 @@ if (isset($_REQUEST["clear"])) { $searchstatslib->clear_search_stats(); } -if ( empty( $_REQUEST["sort_mode"] ) ) { - $sort_mode = 'hits_desc'; -} else { - $sort_mode = $_REQUEST["sort_mode"]; -} +$sort_mode = $_REQUEST["sort_mode"] ?? 'hits_desc'; +$offset = $_REQUEST["offset"] ?? 0; -if (!isset($_REQUEST["offset"])) { - $offset = 0; -} else { - $offset = $_REQUEST["offset"]; -} if (isset($_REQUEST['page'])) { $page = &$_REQUEST['page']; $offset = ($page - 1) * $max_records; } -$gBitSmarty->assignByRef('offset', $offset); +$gBitSmarty->assign('offset', $offset); -if (isset($_REQUEST["find"])) { - $find = $_REQUEST["find"]; -} else { - $find = ''; -} +$find = $_REQUEST["find"] ?? ''; $gBitSmarty->assign('find', $find); -$gBitSmarty->assignByRef('sort_mode', $sort_mode); +$gBitSmarty->assign('sort_mode', $sort_mode); $channels = $searchstatslib->list_search_stats($offset, $max_records, $sort_mode, $find); $cant_pages = ceil($channels["cant"] / $max_records); -$gBitSmarty->assignByRef('cant_pages', $cant_pages); -$gBitSmarty->assign('actual_page', 1 + ($offset / $max_records)); +$gBitSmarty->assign('cant_pages', $cant_pages); +$gBitSmarty->assign('actual_page', 1 + $offset / $max_records); if ($channels["cant"] > ($offset + $max_records)) { $gBitSmarty->assign('next_offset', $offset + $max_records); @@ -73,11 +61,9 @@ if ($offset > 0) { $gBitSmarty->assign('prev_offset', -1); } -$gBitSmarty->assignByRef('channels', $channels["data"]); +$gBitSmarty->assign('channels', $channels["data"]); // Display the template -$gBitSystem->display( 'bitpackage:stats/search_stats.tpl', NULL, array( 'display_mode' => 'display' )); - -?> +$gBitSystem->display( 'bitpackage:stats/search_stats.tpl', null, array( 'display_mode' => 'display' )); diff --git a/templates/admin_search.tpl b/templates/admin_search.tpl index 8eb19a2..5891e64 100644 --- a/templates/admin_search.tpl +++ b/templates/admin_search.tpl @@ -11,7 +11,7 @@ {formlabel label=$output.label for=$item} {forminput} {html_checkboxes name="$item" values="y" checked=$gBitSystem->getConfig($item) labels=false id=$item} - {formhelp note=$output.note page=$output.page} + {formhelp note=$output.note page=$output.page|default:''} {/forminput} {/foreach} @@ -21,7 +21,7 @@ {formlabel label=$output.label for=$item} {forminput} - {formhelp note=$output.note page=$output.page} + {formhelp note=$output.note page=$output.page|default:''} {/forminput} {/foreach} diff --git a/templates/global_mini_search.tpl b/templates/global_mini_search.tpl index 6f07d5f..f97a02b 100644 --- a/templates/global_mini_search.tpl +++ b/templates/global_mini_search.tpl @@ -3,7 +3,7 @@

- {html_options options=$contentTypes name="content_type_guid" selected=$perms[user].level} + {html_options options=$contentTypes name="content_type_guid" selected=0} {* $perms[user].level *}
diff --git a/templates/menu_search.tpl b/templates/menu_search.tpl index 2d3b6d9..0ebf979 100644 --- a/templates/menu_search.tpl +++ b/templates/menu_search.tpl @@ -1,5 +1,5 @@ {strip} -{if $packageMenuTitle} {tr}{$packageMenuTitle}{/tr} {/if} +{if !empty($packageMenuTitle)} {tr}{$packageMenuTitle}{/tr} {/if}