表紙 | 新規 | 一覧 | RSS | 検索 | 閲覧履歴 | 作成履歴 | 更新履歴

do_searchresult関数 - YukiWikiベースのPonyWikiのソースを読んでみる その11

差分表示


[[YukiWikiベースのPonyWikiのソースを読んでみる]] その11

検索機能の中心部。

- AND検索に対応 (スペース区切り)
-- スペースを含むキーワードはダブルクォートでくくれば一つとして処理します
- ページ名(NAM)・更新時刻(MOD)・サブジェクト(SBJ)での昇順(+)・降順(-)が指定可能
- 最大数も指定可能

処理の流れは以下の通り。
- ダブルクォートが実態参照(&verb("))になっているので元に戻す
- ダブルクォートでくくられているキーワードを切り出す
- 先頭にスペースがあれば取り除く
- スペース区切りで残りのキーワードを切り出す
- 全てのページを対象にループを回す。後でソートするのでここではソートしない
-- do_searchresultを呼び出したページ(&verb($form{mypage}))と、システム提供の幾つかのページであればスキップ
-- 検索するページから、&verb()を外す
-- 全てのキーワードでページの内容とページ名を検索し、そのヒット数を数える
-- ページの内容かページ名のヒット数が、キーワードの数と一致すれば該当リストに追加する
- 指定されたソート順で該当リストをソートし、htmlを出力する
- 結果を戻す

---(
sub do_searchresult {
    my ($argword,$keyopt,$loop_cnt)  = @_;
    my $counter = 0;
    my $html;
    my %name_list; my %mod_list; my %data_list;
    my $sortopt;
	my ($argword,$keyopt,$loop_cnt)  = @_;
	my $counter = 0;
	my $html;
	my %name_list; my %mod_list; my %access_list;
	my $sortopt;

    my $word;
    my @words;
    my @tmpwords;
    my $body_hit_cnt;
    my $page_hit_cnt;
	my $word;
	my @words;
	my @tmpwords;
	my $page_hit_cnt;

    $argword =~ s|"|"|g;
    for (my $cnt = 0; $argword =~ s/"([^"]*)"//; $cnt++){
        $words[$cnt] = $1;
    }
    $argword =~ s|^\s||;
    @tmpwords = split(/\s+/, $argword);
    @words = (@words, @tmpwords);
    if(!@words){
        return undef;
    }
	$argword =~ s|"|"|g;
	for (my $cnt = 0; $argword =~ s/"([^"]*)"//; $cnt++){
		$words[$cnt] = $1;
	}
	$argword =~ s|^\s||;
	@tmpwords = split(/\s+/, $argword);
	@words = (@words, @tmpwords);
	if(!@words){
		return undef;
	}

    while (my $page = each(%database)) {
        next if $page =~ /^$[[RecentChanges]]$/;
        next if $page =~ /^$[[RecentCreates]]$/;
        next if $page =~ /^$[[FrontPage]]$/;
        next if $page =~ /^\Q$form{mypage}\E$/;

        my $tmp_db = $database{$page};
        $tmp_db =~ s/\[\[|\]\]//g;
        for (my $cnt=0,$body_hit_cnt=0,$page_hit_cnt=0; $cnt < @words; $cnt++) {
            $word = $words[$cnt];
            if ($tmp_db =~ /\Q$word\E/i) {
                $body_hit_cnt++;
            }
            if ($page =~ /\Q$word\E/i) {
                $page_hit_cnt++;
            }
        }

        if($body_hit_cnt == @words or $page_hit_cnt == @words){
            $name_list{$page} = &escape(&get_subjectline($page));
            $mod_list{$page} = &info_to_digit(&get_info($page, $info_ConflictChecker));
            $counter++;
        }
    }

    if ($counter == 0) {
        $html .= "";
    } else {
        $html .= qq|<ul>|;

        if ($keyopt eq 'NAM+') {        # Sort Order by PageName
            $sortopt = 'sort keys %name_list';
        } elsif ($keyopt eq 'MOD+') {    # Sort Order by LastMod
            $sortopt = 'sort {$mod_list{$a} cmp $mod_list{$b}} keys %mod_list';
        } elsif ($keyopt eq 'SBJ+') {    # Sort Order by Subject
            $sortopt = 'sort {$name_list{$a} cmp $name_list{$b}} keys %name_list';
        } elsif ($keyopt eq 'NAM-') {    # Sort Order by PageName DESC
            $sortopt = 'sort { $b cmp $a } keys %name_list';
        } elsif ($keyopt eq 'MOD-') {    # Sort Order by LastMod DESC
            $sortopt = 'sort {$mod_list{$b} cmp $mod_list{$a}} keys %mod_list';
        } elsif ($keyopt eq 'SBJ-') {    # Sort Order by Subject DESC
            $sortopt = 'sort {$name_list{$b} cmp $name_list{$a}} keys %name_list';
        } else {                        # Sort Order by DEFAULT
            $sortopt = 'sort keys %name_list';
        }

        foreach my $page (eval $sortopt) {
            $html .= qq(<li><a href ="$url_cgi?@{[&encode($page)]}">@{[&escape($page)]}</a>@{[&escape(&get_subjectline($page))]}</li>\n); 
            $loop_cnt = $loop_cnt -1;
            if ($loop_cnt == 0) {last;}
        }
        $html .= qq|</ul>|;
    }

    return $html;
	&open_search_index;
	for (my $i=0; $i < @search_index; $i++){
		my $index_data = $search_index[$i];
		chomp $index_data;
		next if $index_data =~ /^$[[FrontPage]]\t/;
		next if $index_data =~ /^\Q$form{mypage}\E\t/;
		
		my ($page,$idx_contents,$idx_subject,$mtime) = split(/\t/,$index_data);
		
		
		for (my $cnt=0,$page_hit_cnt=0; $cnt < @words; $cnt++) {
			$word = $words[$cnt];
			if ($idx_contents =~ /\Q$word\E/i or $page =~ /\Q$word\E/i) {
				$page_hit_cnt++;
			}
		}
	
# For debug
#		$html .= "$page  A$idx_subject B  C$mtime D".'<BR>';
	
		if($page_hit_cnt == @words){
			$name_list{$page} = &escape($idx_subject);
			$mod_list{$page} = $mtime;
			if($keyopt =~ /ACC/i) { $access_list{$page} = &get_info($page, $info_UniqAccessCount); }
			$counter++;
		}
	}
	&close_search_index;
	
	if ($counter == 0) {
		$html .= "";
	} else {
		$html .= qq|<ul>|;
	
		if ($keyopt eq 'NAM+') {		# Sort Order by PageName
			$sortopt = 'sort keys %name_list';
		} elsif ($keyopt eq 'MOD+') {	# Sort Order by LastMod
			$sortopt = 'sort {$mod_list{$a} <=> $mod_list{$b} or $a cmp $b} keys %mod_list';
		} elsif ($keyopt eq 'SBJ+') {	# Sort Order by Subject
			$sortopt = 'sort {$name_list{$a} cmp $name_list{$b} or $a cmp $b} keys %name_list';
		} elsif ($keyopt eq 'ACC+' or $keyopt eq 'acc+' ) {	# Sort Order by Access Count
			$sortopt = 'sort {$access_list{$a} <=> $access_list{$b} or $a cmp $b} keys %access_list';
		
		} elsif ($keyopt eq 'NAM-') {	# Sort Order by PageName DESC
			$sortopt = 'sort { $b cmp $a } keys %name_list';
		} elsif ($keyopt eq 'MOD-') {	# Sort Order by LastMod DESC
			$sortopt = 'sort {$mod_list{$b} <=> $mod_list{$a} or $b cmp $a} keys %mod_list';
		} elsif ($keyopt eq 'SBJ-') {	# Sort Order by Subject DESC
			$sortopt = 'sort {$name_list{$b} cmp $name_list{$a} or $b cmp $a} keys %name_list';
		} elsif ($keyopt eq 'ACC-' or $keyopt eq 'acc-' ) {	# Sort Order by Access Count
			$sortopt = 'sort {$access_list{$b} <=> $access_list{$a} or $b cmp $a} keys %access_list';
		
		} else {						# Sort Order by DEFAULT
			$sortopt = 'sort keys %name_list';
		}
		
		foreach my $page (eval $sortopt) {
			if ($keyopt =~ /\Qacc\E/) {
				$html .= qq(<li><a href ="$url_cgi?@{[&encode($page)]}">@{[&escape($page)]}</a>@{[&escape(&get_subjectline($page))]}   $access_list{$page}access.</li>\n); 
			} else {
				$html .= qq(<li><a href ="$url_cgi?@{[&encode($page)]}">@{[&escape($page)]}</a>@{[&escape(&get_subjectline($page))]}</li>\n); 
			}
			$loop_cnt = $loop_cnt -1;
			if ($loop_cnt == 0) {last;}
		}
		$html .= qq|</ul>|;
	}
	
# For debug
#	$html .= join("<br>",@words);
	
	return $html;
}

---)

----
[[#trackback]]

先頭へ