<?php if(!defined('PmWiki')) exit();

$RecipeInfo['SortByScore']['Version'] = '2017-11-10';

/*
	SortByScore for PmWiki	
	Copyright 2006-2007 Mateusz Czaplinski (mateusz@czaplinski.pl)

	This file is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published
	by the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	---- Usage Information: ----

	* Put this file in 'cookbook/' directory of your PmWiki installation
	* In your 'local/config.php' file add the following line:

		include_once("$FarmD/cookbook/sortbyscore.php");

	* This enables additional formatting for (:pagelist:) and Search action

		(:pagelist ... fmt=score ...:)
		- sorts search results by number of search terms
		  occuring in pages. The final list contains also
		  excerpts of pages, with search terms shown in bold.

		(:searchbox fmt=score:)
		- adds this functionality to the Search button.

	* If you want to tweak the recipe for your language, please
	  add an entry for 'score' in your PmWikiXx.XLPageCookbook.

	---- Comments and More Information: ----

		http://pmwiki.org/wiki/Cookbook/SortByScore

	---- History: ----

	* 2017-11-10 Update for PHP 5.5-7.2, requires PmWiki 2.2.56+ (by Petko pmwiki.org/petko )
	* 2007-09-32 - v1.2
	  - removed the requirement for Cookbook:Excerpts recipe,
	    not showing excerpts now unless Cookbook:Excerpts included
	    before (still can be disabled by setting $EnableSortByScoreExcerpts=0)
	* 2007-09-26 - v1.1 
	  - compatible with new pmwiki-2.2.0-beta63
	  - title matches get bonus score
	  - some bug fixes & minor tweaks
	* 2006-12-21 - v1.0 - initial release

*/


###########
## Search results sorted by score - number of hits (words found) in page
##-- Notes:
## - Requires (:excerpt:) recipe - also for ExcerptToupper()
## - You can redefine the 'score' text on your PmWikiXx.XLPageCookbook
###########

# Multiplier for matches inside page's title (or name if no title)
SDV($SortByScoreTitleBonus,100);

# Use fmt=score as the default format for (:searchresults:)
SDV($SortByScoreDefault,true);

if( $SortByScoreDefault )
 Markup('searchresults', 'directives',
  '/\\(:searchresults(\\s+.*?)?:\\)/i',
  "MarkupSearchresultsByScore");

function MarkupSearchresultsByScore($m) {
  extract($GLOBALS["MarkupToHTML"]); # get $pagename
  return FmtPageList($GLOBALS['SearchResultsFmt'], 
    $pagename, array('req' => 1, 'request'=>1, 'fmt' => 'score', 'o' => $m[1]));
}

# Format of a results line.
# Special additional variables: $score, $terms
if( isset($RecipeInfo['Excerpts']) && IsEnabled($EnableSortByScoreExcerpts,1) )
	SDV($SortByScoreFmt, ":[[\$FullName|[-\$Group.-]\$Title]] - ''\$[score] \$score'': (:excerpts \$FullName \$terms:)");
else
	SDV($SortByScoreFmt, ":[[\$FullName|[-\$Group.-]\$Title]] - ''\$[score] \$score'':");

$FPLFormatOpt['score']['fn']='FPLScore';
function FPLScore($pagename, &$matches, $opt) {
	global $SortByScoreTitleBonus, $SortByScoreFmt;
	$matches = MakePageList($pagename,$opt);
	$terms = $opt[''];
	for($n=0;$n<count($matches);$n++) {
		$page=&$matches[$n];
		$pn=$page['pagename'];
		## Count hits
		$page['score']=0;
		$count= &$page['score'];
		if(!$terms) continue;
		$text=ReadPage($pn);
		$text=SortByScoreToupper($text['text']);
		$count=0;
		foreach( $terms as $term ) {
			$term = SortByScoreToupper($term);
			$count += substr_count($text,$term);
			$count += substr_count(SortByScoreToupper(FmtPageName('$Title',$pn)),$term)
				* $SortByScoreTitleBonus;
		}		
	}

	## Sort by score, descending (if equal, then by name)
	usort($matches, 'usortByScore');
	if (@$opt['count']) array_splice($matches, $opt['count']); 

	if($terms) $terms = '"'.implode('" "',$terms).'"';
	$out = array();
	foreach($matches as $p) {
		if(!$p['pagename']) continue; ## empty pagenames - probably deleted pages ?
		$g = array('$score'=>$p['score'], '$terms'=>$terms);
		$out[] = FmtPageName(
			str_replace(array_keys($g),array_values($g),$SortByScoreFmt),$p['pagename']);
	}
	return '<div class="fplscore">' .
		MarkupToHTML( $pagename, "\n\n".implode("\n",$out)."\n\n" ) .
		'</div>';
}
function usortByScore($x,$y) {
  return ($k=$y['score']-$x['score']) ? $k : (@strcasecmp($x['name'],$y['name']));
}

function SortByScoreToupper($text) {
	if( function_exists('utf8toupper') )
		return utf8toupper($text);
	else
		return strtoupper($text);
}