<?php
/**
* 此模块用于处理启用全文检索及其相关设置的问题。
*
* @package 		dvphp
* @author		xiaodu@dv
* @version		$Revision: 1.0 beta $
* @date 		$Date: 2006/11/06 $
* @copyright 	http://p.dvbbs.net/license.html
*
*/
ini_set('display_errors','1');
define('THIS_SCRIPT', 'fulltext_settings');
require_once 'global.php';
require INC_PATH.'BoardCache.class.php';
require INC_PATH.'FileHandler.class.php';
checklogin();
if ( strpos($sysinfo['flag'],'29,') === false ){
	head();
	show_msg($lang['readme_tit'],$lang['error.str1'],0,'','','','');
	exit;
}

$lang=load_lang($lang, 'fulltext_settings' );

if (empty($doaction)) {	//	显示默认界面
	head();
	require printout('fulltext_settings');
	footer();
} else {

	global $__phparray;
	$__phparray = array('errstr'=>'');

	//系统检测到您的Mysql服务器的ft_min_word_len的值为{$TPL_ft_min_word_len}。要开启全文检索功能，需要ft_min_word_len的值小于等于2。
	if (($ftminwordlen = getftminwordlen()) > 2) {
		$__phparray['errstr'] = str_replace('{$TPL_ft_min_word_len}', $ftminwordlen, $lang['ft_settings.err0']);
		writejscode();
		exit;
	}

	if ('rebuild_init' === $doaction) {	//	执行转换前的准备

		$__phparray['RecordCount'] = 0;
		$__phparray['TableList'] = array();

		$tablelist =& gettablelist();
		foreach ($tablelist AS $tablename) {
			$recordcount = $db->scalar("SELECT COUNT(1) FROM ".$db->escape_string($tablename));
			$__phparray['TableList'][] = array($tablename, $recordcount);
			$__phparray[$tablename]['RecordCount'] = $recordcount;
			$__phparray[$tablename]['AffectedRows'] = 0;
			$__phparray['RecordCount'] += $recordcount;
		}//end foreach
		writejscode();
		exit;

	} elseif ('disable_settings' === $doaction) {	//	关闭论坛的全文检索功能

		saveftsettings(array(0=>0));
		$__phparray['settings_disabled'] = true;
		writejscode();
		exit;

	} elseif ('disable_keys' === $doaction) {	//	禁用索引表上的键

		$db->query("/*!40000 ALTER TABLE {$dv}topic_ft DISABLE KEYS */");//	禁用索引表上的键，这有助于提高索引的更新速度
		$db->query("/*!40000 ALTER TABLE {$dv}bbs_ft DISABLE KEYS */");//	禁用索引表上的键，这有助于提高索引的更新速度
		$__phparray['keys_disabled'] = true;
		writejscode();
		exit;

	} elseif ('replace_data' === $doaction) {	//	执行转换

		$__phparray['all_done'] = false;
		$__phparray['affected_rows'] = 0;
		$__phparray['begin_id'] = 0;
		$__phparray['dest_tablename'] = '';

		if (!is_numeric($begin_id) OR $begin_id <= 0) {
			$begin_id = 1;
		}

		if (!$dest_tablename) {	//	丢失参数——dest_tablename
			$__phparray['errstr'] = $lang['ft_settings.err1'];
			writejscode();
			exit;
		}

		$tablelist =& gettablelist();
		if (!in_array($dest_tablename, $tablelist)) {	//	非法的参数dest_tablename——表名称{$TPL_tablename}不正确！
			$__phparray['errstr'] = str_replace('{$TPL_tablename}', $dest_tablename, $lang['ft_settings.err2']);
			writejscode();
			exit;
		}

		$__phparray['dest_tablename'] = $dest_tablename;

		$dest_tablename = $db->escape_string($dest_tablename);
		$istopic = ($dv.'topic' == $dest_tablename||$dv.'savvy_topic' == $dest_tablename) ? true : false;
		$istopic AND $topictype=($dv.'savvy_topic' == $dest_tablename) ? 1 : 0;//主题类型,1：论坛知道;0:帖子主题
		if (true === $istopic) {
			$stmt = "SELECT topicid AS id, boardid, locktopic, posttable, title AS topic FROM {$dest_tablename} WHERE topicid>='{$begin_id}'";
		} else {
			$stmt = "SELECT announceid AS id, rootid, boardid, locktopic, topic, body FROM {$dest_tablename} WHERE announceid>='{$begin_id}'";
		}

		$rebuild_stmts = array();
		$pagesize = 1000;
		$beginid = $affected_rows = 0;
		($query = $db->query($stmt, array('pageSize'=>$pagesize))) AND ($affected_rows = $db->affected_rows());
		if ($affected_rows > 0) {
			$__phparray['affected_rows'] = $affected_rows;
			while ($dbinfo =& $db->fetch_array($query)) {
				$dbinfo = array_change_key_case($dbinfo, CASE_LOWER);
				$beginid = $dbinfo['id'] + 1;
				$topic =divChineseWordSegment(trim($dbinfo['topic']));
				$body = divChineseWordSegment(trim($dbinfo['body']));		
				if (true === $istopic) {
				('' !== $topictitle) AND ($rebuild_stmts[] = "REPLACE INTO ".$dv."topic_ft SET topicid=".$dbinfo['id'].", boardid=".$dbinfo['boardid'].", locktopic=".$dbinfo['locktopic'].", posttable='".$db->escape_string($dbinfo['posttable'])."', topicindex='".$db->escape_string($topic)."', issavvytopic={$topictype}");
				} else {
				('' !== $body) AND ($rebuild_stmts[] = "REPLACE INTO ".$dv."bbs_ft SET announceid=".$dbinfo['id'].", rootid=".$dbinfo['rootid'].", boardid=".$dbinfo['boardid'].", locktopic=".$dbinfo['locktopic'].", posttable='".$dest_tablename."', topicindex='".$db->escape_string($topic)."', bodyindex='".$db->escape_string($body)."'");
				}
			}//end while
			$db->free_result($query);	//	释放结果集
			//Start 执行索引重建的SQL语句
			if (!empty($rebuild_stmts)) {
				foreach ($rebuild_stmts AS $stmt) {
					$db->query($stmt, array('type'=>'SILENT'));
					if ($db->errno()) {
						$__phparray['errstr'] = $db->error();
						break;
					}
				}//end foreach
			}
			//End 执行索引重建的SQL语句
		} else {
			$nextindex = 0;
			foreach ($tablelist AS $index => $tablename) {
				if ($tablename == $dest_tablename) {
					$nextindex = $index + 1;
					break;
				}
			}//end foreach
			if (0 === $nextindex OR !isset($tablelist[$nextindex])) {	//	所有全文索引成功建立！
				$__phparray['all_done'] = true;
			} else {
				$__phparray['dest_tablename'] = $tablelist[$nextindex];
			}
		}
		$__phparray['begin_id'] = $beginid;
		writejscode();
		exit;

	} elseif ('enable_keys_topic_ft' === $doaction) {	//	所有数据已更新到 dv_topic_ft 表，此时应该启用此表上的键

		$__phparray = array('errstr'=>'', 'keys_enabled'=>false);
		$db->query("/*!40000 ALTER TABLE {$dv}topic_ft ENABLE KEYS */");	//	恢复索引表上的键，让全文索引生效
		$__phparray['keys_enabled'] = true;
		writejscode();
		exit;

	} elseif ('check_keys_status_topic_ft' === $doaction) {	//	检测在 dv_topic_ft 表上的键是否已全部启用
		$keys_enabled = true;
		if ($query = $db->query("SHOW INDEX FROM {$dv}topic_ft")) {
			while ($dbinfo =& $db->fetch_array($query)) {
				if ('disabled' === strtolower($dbinfo['Comment'])) {
					$keys_enabled = false;
					break;
				}
			}//end while
			$db->free_result($query);
		}
		$__phparray['keys_enabled'] = $keys_enabled;
		writejscode();
		exit;
	} elseif ('enable_keys_bbs_ft' === $doaction) {	//	所有数据已更新到 dv_bbs_ft 表，此时应该启用此表上的键

		$__phparray = array('errstr'=>'', 'keys_enabled'=>false);
		$db->query("/*!40000 ALTER TABLE {$dv}bbs_ft ENABLE KEYS */");	//	恢复索引表上的键，让全文索引生效
		$__phparray['keys_enabled'] = true;
		writejscode();
		exit;

	} elseif ('check_keys_status_bbs_ft' === $doaction) {	//	检测在 dv_bbs_ft 表上的键是否已全部启用
		$keys_enabled = true;
		if ($query = $db->query("SHOW INDEX FROM {$dv}bbs_ft")) {
			while ($dbinfo =& $db->fetch_array($query)) {
				if ('disabled' === strtolower($dbinfo['Comment'])) {
					$keys_enabled = false;
					break;
				}
			}//end while
			$db->free_result($query);
		}
		$__phparray['keys_enabled'] = $keys_enabled;
		writejscode();
		exit;
	} elseif ('save_settings' === $doaction) {	//	提交保存设置
		saveftsettings(array(0=>intval($_POST['ft_settings(0)']), 1=>intval($_POST['ft_settings(1)']), 2=>intval($_POST['ft_settings(2)'])));
		head();
		show_msg($lang['ft_settings.title'], $lang['ft_settings.str1'], 1,'', '', $lang['url'],$lang['comback']);	//
		footer();
	}
}

/**
 * Description 检测 Mysql 的 ft_min_word_len 是否大于等于 2
 * @author xiaodu@dv
 * @param string 要检测的目录
 * @return mixed 如果目录目录可写，返回 TRUE ，否则返回 FALSE 。
 */
function getftminwordlen()
{
	static $ft_min_word_len;
	if (!isset($ft_min_word_len)) {
		global $db, $dv;
		if ($query = $db->query("SHOW VARIABLES LIKE 'ft_min_word_len'")) {
			if ($dbinfo =& $db->fetch_row($query)) {
				$ft_min_word_len = $dbinfo[1];
			}
		}
	}
	return $ft_min_word_len;
}//end function check_ftminwordlen

function apply_ft()
{
	if (getftminwordlen() > 2) {
		return false;
	}
	global $dv, $db;
}//end function apply_ft
function gettablelist()

{
	static $tablelist;	
	if (!isset($tablelist)) {
		global $dv, $db;
		$tablelist[] = $dv.'savvy_topic';
		$tablelist[] = $dv.'topic';
		if ($query = $db->query("SELECT tablename FROM {$dv}tablelist")) {
			while ($dbinfo =& $db->fetch_row($query)) {
				$tablelist[] = $dbinfo[0];
			}//end while
		}
		
	}
	return $tablelist;
}//end function gettablelist
function writejscode()
{
	global $doaction, $__phparray;
	if (!isset($__phparray['doaction'])) {
		$__phparray['doaction'] = $doaction;
	}
	$jscode = var_export2js($__phparray, true);
	print <<<EOT
<script type="text/javascript">
	function __CallBack()
	{
		window.parent.DoResponse($jscode);
	}//end function __CallBack
	setTimeout('__CallBack()', 100);	//	这里不仅是为了增强客户端的显示效果，还给服务器多了 100 毫秒的喘息时间
</script>
EOT;
	exit;
}//end function writejscode
function saveftsettings($argsettings = array())	//
{
	global $dv, $db;
	$forum_settings = $db->scalar("SELECT forum_setting FROM {$dv}setup");
	$arrtmp1 = explode('|||', $forum_settings);
	$arrtmp2 = explode(',', $arrtmp1[1]);
	$ft_settings = explode('|', $arrtmp2[101]);

	isset($argsettings[0]) AND ($ft_settings[0] = $argsettings[0]);
	isset($argsettings[1]) AND ($ft_settings[1] = $argsettings[1]);
	isset($argsettings[2]) AND ($ft_settings[2] = $argsettings[2]);

	$arrtmp2[101] = implode('|', $ft_settings);
	$arrtmp1[1] = implode(',', $arrtmp2);
	$forum_settings = implode('|||', $arrtmp1);

	$db->query("UPDATE {$dv}setup SET forum_setting='".$db->escape_string($forum_settings)."'");
	require_once INC_PATH.'BoardCache.class.php';
	$objcache =& new BoardCache($db);
	$objcache->createForumSetting();
	$objcache->createmailconfig();
	unset($objcache);
}//end function saveftsettings

function divChineseWordSegment($str){
	$arrStopWords =& DV_GetStopWordList();
	//过滤所有HTML标签
	$str = preg_replace('#<[a-zA-Z]+?.*?>|</[a-zA-Z]+?.*?>#is', '', $str);
	//过滤所有stopword
	$str = str_replace($arrStopWords['StrRepl'],' ',$str);
	//$str = preg_replace($arrStopWords['PregRepl'],' ',$str);
	$tmp="";
	$s=0;
	$cc=false;
	for($i=0;$i<strlen($str);$i++){
		$a=$str[$i];
		$a=ord($str[$i]);
		if(ord($str[$i])&0x80){
			//查找两个连续的中文字符
			if($cc)$tmp.=" ".substr($str,$s,4);
			$cc=true;
			$s=$i;
			$i++;
		}else{
			if($cc)$tmp.=" ";
			$tmp.=$str[$i];
			$cc=false;
		}

	}
	return $tmp;
}
?>