'[pagename]', 's' => false, 'debug' => false); } function spelling_similarity($subject) { $spelling_similarity_score = 0; similar_text($subject, $this->_searchterm, &$spelling_similarity_score); return $spelling_similarity_score; } function sound_similarity($subject) { $sound_similarity_score = 0; // similar_text() automatically calculates a percentage. // http://www.php.net/manual/en/function.similar-text.php similar_text(metaphone($subject), $this->_searchterm_metaphone, &$sound_similarity_score); return $sound_similarity_score; } function averageSimilarities($subject) { return ($this->spelling_similarity($subject) + $this->sound_similarity($subject)) / 2; } function collectSimilarPages(&$list, &$dbi) { if (! defined('MIN_SCORE_CUTOFF')) define('MIN_SCORE_CUTOFF', 33); $this->_searchterm_metaphone = metaphone($this->_searchterm); $allPages = $dbi->getAllPages(); while ($pagehandle = $allPages->next()) { $pagename = $pagehandle->getName(); $similarity_score = $this->averageSimilarities($pagename); if ($similarity_score > MIN_SCORE_CUTOFF) $list = array_merge($list, array($pagename => $similarity_score)); } } function sortCollectedPages(&$list) { array_multisort(&$list, SORT_NUMERIC, SORT_DESC); } function addTableCaption(&$table, &$dbi) { if ($dbi->isWikiPage($this->_searchterm)) $link = WikiLink($this->_searchterm, 'auto'); else $link = $this->_searchterm; $caption = fmt("These page titles match fuzzy with '%s'", $link); $table->pushContent(HTML::caption(array('align'=>'top'), $caption)); } function addTableHead(&$table) { $row = HTML::tr(HTML::td(_("Name")), HTML::td(array('align' => 'right'), _("Score"))); if ($this->debug) $this->_pushDebugHeadingTDinto($row); $table->pushContent(HTML::thead($row)); } function addTableBody(&$list, &$table) { if (! defined('HIGHLIGHT_ROWS_CUTOFF_SCORE')) define('HIGHLIGHT_ROWS_CUTOFF_SCORE', 60); $tbody = HTML::tbody(); foreach ($list as $found_pagename => $score) { $row = HTML::tr(array('class' => $score > HIGHLIGHT_ROWS_CUTOFF_SCORE ? 'oddrow' : 'evenrow'), HTML::td(WikiLink($found_pagename)), HTML::td(array('align' => 'right'), round($score))); if ($this->debug) $this->_pushDebugTDinto($row, $found_pagename); $tbody->pushContent($row); } $table->pushContent($tbody); } function formatTable(&$list, &$dbi) { $table = HTML::table(array('cellpadding' => 2, 'cellspacing' => 1, 'border' => 0, 'class' => 'pagelist')); $this->addTableCaption($table, &$dbi); $this->addTableHead($table); $this->addTableBody($list, $table); return $table; } function run($dbi, $argstr, $request) { $args = $this->getArgs($argstr, $request); extract($args); if (empty($page)) return ''; $this->debug = $debug; $this->_searchterm = $s ? $s : $page; $this->_list = array(); $this->collectSimilarPages($this->_list, &$dbi); $this->sortCollectedPages($this->_list); return $this->formatTable($this->_list, &$dbi); } function _pushDebugHeadingTDinto(&$row) { $row->pushContent(HTML::td(_("Spelling Score")), HTML::td(_("Sound Score")), HTML::td('Metaphones')); } function _pushDebugTDinto(&$row, $pagename) { // This actually calculates everything a second time for each page // but the individual scores are retained separately. $debug_spelling = round($this->spelling_similarity($pagename), 1); $debug_sound = round($this->sound_similarity($pagename), 1); $debug_metaphone = sprintf("(%s, %s)", metaphone($pagename), $this->_searchterm_metaphone); $row->pushcontent(HTML::td(array('align' => 'center'), $debug_spelling), HTML::td(array('align' => 'center'), $debug_sound), HTML::td($debug_metaphone)); } }; // Local Variables: // mode: php // tab-width: 8 // c-basic-offset: 4 // c-hanging-comment-ender-p: nil // indent-tabs-mode: nil // End: ?>