mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
fixes result list ordering issue
engine give nicer results with adequate pagination. Adding icon and reference to course origine. should contribute to close many global search related issues from http://tracker.moodle.org/browse/MDL-14646 startpoint
This commit is contained in:
parent
f7ed268752
commit
3efa38a41d
@ -18,7 +18,9 @@
|
||||
|
||||
/*
|
||||
// function reference
|
||||
function search_collect_searchables($namelist=false, $verbose=true){
|
||||
function search_get_document_types($prefix = 'SEARCH_TYPE_') {
|
||||
function search_get_document_types($prefix = 'X_SEARCH_TYPE_') {
|
||||
function search_get_additional_modules() {
|
||||
function search_shorten_url($url, $length=30) {
|
||||
function search_escape_string($str) {
|
||||
@ -35,8 +37,8 @@ include "{$CFG->dirroot}/search/searchtypes.php";
|
||||
|
||||
/**
|
||||
* collects all searchable items identities
|
||||
* @param boolean $namelist
|
||||
* @param boolean $verbose
|
||||
* @param boolean $namelist if true, only returns list of names of searchable items
|
||||
* @param boolean $verbose if true, prints a discovering status
|
||||
* @return an array of names or an array of type descriptors
|
||||
*/
|
||||
function search_collect_searchables($namelist=false, $verbose=true){
|
||||
@ -53,13 +55,13 @@ function search_collect_searchables($namelist=false, $verbose=true){
|
||||
foreach($mods as $mod){
|
||||
if (in_array($mod->name, $searchabletypes)){
|
||||
$mod->location = 'internal';
|
||||
$searchables[] = $mod;
|
||||
$searchables[$mod->name] = $mod;
|
||||
$searchables_names[] = $mod->name;
|
||||
} else {
|
||||
$documentfile = $CFG->dirroot."/mod/{$mod->name}/search_document.php";
|
||||
$mod->location = 'mod';
|
||||
if (file_exists($documentfile)){
|
||||
$searchables[] = $mod;
|
||||
$searchables[$mod->name] = $mod;
|
||||
$searchables_names[] = $mod->name;
|
||||
}
|
||||
}
|
||||
@ -82,7 +84,7 @@ function search_collect_searchables($namelist=false, $verbose=true){
|
||||
$documentfile = $CFG->dirroot."/blocks/{$block->dirname}/search_document.php";
|
||||
if (file_exists($documentfile)){
|
||||
$mod->location = 'blocks';
|
||||
$blocks_searchables[] = $block;
|
||||
$blocks_searchables[$block->name] = $block;
|
||||
$searchables_names[] = $block->name;
|
||||
}
|
||||
}
|
||||
@ -105,7 +107,7 @@ function search_collect_searchables($namelist=false, $verbose=true){
|
||||
}
|
||||
|
||||
/**
|
||||
* returns all the document type constants
|
||||
* returns all the document type constants that are known in core implementation
|
||||
* @param prefix a pattern for recognizing constants
|
||||
* @return an array of type labels
|
||||
*/
|
||||
@ -138,7 +140,7 @@ function search_get_additional_modules() {
|
||||
foreach($extras as $extra) {
|
||||
$temp->name = $extra;
|
||||
$temp->location = 'internal';
|
||||
$ret[] = clone($temp);
|
||||
$ret[$temp->name] = clone($temp);
|
||||
}
|
||||
return $ret;
|
||||
} //search_get_additional_modules
|
||||
|
@ -93,8 +93,9 @@
|
||||
|
||||
$query_string = '';
|
||||
|
||||
// get all available module types
|
||||
// get all available module types adding third party modules
|
||||
$module_types = array_merge(array('all'), array_values(search_get_document_types()));
|
||||
$module_types = array_merge($module_types, array_values(search_get_document_types('X_SEARCH_TYPE')));
|
||||
$adv->module = in_array($adv->module, $module_types) ? $adv->module : 'all';
|
||||
|
||||
// convert '1 2' into '+1 +2' for required words field
|
||||
@ -141,7 +142,7 @@
|
||||
$page_number = 1;
|
||||
}
|
||||
|
||||
//run the query against the index
|
||||
//run the query against the index ensuring internal coding works in UTF-8
|
||||
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8());
|
||||
$sq = new SearchQuery($query_string, $page_number, 10, false);
|
||||
}
|
||||
@ -308,7 +309,8 @@
|
||||
<?php
|
||||
print_box_end();
|
||||
|
||||
// prints all the results in a box
|
||||
/// prints all the results in a box
|
||||
|
||||
if ($sq->is_valid()) {
|
||||
print_box_start();
|
||||
|
||||
@ -336,26 +338,42 @@
|
||||
$typestr = get_string('type', 'search');
|
||||
$scorestr = get_string('score', 'search');
|
||||
$authorstr = get_string('author', 'search');
|
||||
|
||||
$searchables = search_collect_searchables(false, false);
|
||||
|
||||
foreach ($hits as $listing) {
|
||||
|
||||
$iconpath = $CFG->modpixpath.'/'.$listing->doctype.'/icon.gif';
|
||||
$coursename = get_field('course', 'fullname', 'id', $listing->courseid);
|
||||
$courseword = mb_convert_case(get_string('course', 'moodle'), MB_CASE_LOWER, 'UTF-8');
|
||||
//if ($CFG->unicodedb) {
|
||||
//$listing->title = mb_convert_encoding($listing->title, 'auto', 'UTF8');
|
||||
//}
|
||||
$title_post_processing_function = $listing->doctype.'_link_post_processing';
|
||||
require_once "{$CFG->dirroot}/search/documents/{$listing->doctype}_document.php";
|
||||
$searchable_instance = $searchables[$listing->doctype];
|
||||
if ($searchable_instance->location == 'internal'){
|
||||
require_once "{$CFG->dirroot}/search/documents/{$listing->doctype}_document.php";
|
||||
} else {
|
||||
require_once "{$CFG->dirroot}/{$searchable_instance->location}/{$listing->doctype}/search_document.php";
|
||||
}
|
||||
if (function_exists($title_post_processing_function)) {
|
||||
$listing->title = $title_post_processing_function($listing->title);
|
||||
}
|
||||
|
||||
print "<li value='".($listing->number+1)."'><a href='".str_replace('DEFAULT_POPUP_SETTINGS', DEFAULT_POPUP_SETTINGS ,$listing->url)."'>$listing->title</a><br />\n"
|
||||
."<em>".search_shorten_url($listing->url, 70)."</em><br />\n"
|
||||
."{$typestr}: ".$listing->doctype.", {$scorestr}: ".round($listing->score, 3);
|
||||
echo "<li value='".($listing->number+1)."'><a href='"
|
||||
.str_replace('DEFAULT_POPUP_SETTINGS', DEFAULT_POPUP_SETTINGS ,$listing->url)
|
||||
."'><img align=\"top\" src=\"".$iconpath
|
||||
."\" class=\"activityicon\" alt=\"\"/> $listing->title</a><strong> (".$courseword.": '".$coursename."')</strong><br />\n";
|
||||
// print "<li value='".($listing->number+1)."'><a href='".str_replace('DEFAULT_POPUP_SETTINGS', DEFAULT_POPUP_SETTINGS ,$listing->url)."'>$listing->title</a><br />\n"
|
||||
// ."<em>".search_shorten_url($listing->url, 70)."</em><br />\n"
|
||||
// ."{$typestr}: ".$listing->doctype.", {$scorestr}: ".round($listing->score, 3);
|
||||
if (!empty($listing->author)){
|
||||
print ", {$authorstr}: ".$listing->author."\n"
|
||||
echo ", {$authorstr}: ".$listing->author."\n"
|
||||
."</li>\n";
|
||||
}
|
||||
}
|
||||
print "</ol>";
|
||||
print $page_links;
|
||||
echo "</ol>";
|
||||
echo $page_links;
|
||||
}
|
||||
print_box_end();
|
||||
?>
|
||||
|
@ -26,7 +26,8 @@ public $url,
|
||||
$doctype,
|
||||
$author,
|
||||
$score,
|
||||
$number;
|
||||
$number,
|
||||
$courseid;
|
||||
}
|
||||
|
||||
|
||||
@ -220,6 +221,7 @@ class SearchQuery {
|
||||
global $USER;
|
||||
|
||||
$term = mb_convert_case($this->term, MB_CASE_LOWER, 'UTF-8');
|
||||
$page = optional_param('page', 1, PARAM_INT);
|
||||
|
||||
//experimental - return more results
|
||||
$strip_arr = array('author:', 'title:', '+', '-', 'doctype:');
|
||||
@ -233,49 +235,58 @@ class SearchQuery {
|
||||
|
||||
if ($hitcount == 0) return array();
|
||||
|
||||
$totalpages = ceil($hitcount/$this->results_per_page);
|
||||
$resultdoc = new SearchResult();
|
||||
$resultdocs = array();
|
||||
$searchables = search_collect_searchables(false, false);
|
||||
|
||||
$realindex = 0;
|
||||
|
||||
/**
|
||||
if (!$all) {
|
||||
if ($hitcount < $this->results_per_page) {
|
||||
if ($finalresults < $this->results_per_page) {
|
||||
$this->pagenumber = 1;
|
||||
} else if ($this->pagenumber > $totalpages) {
|
||||
} elseif ($this->pagenumber > $totalpages) {
|
||||
$this->pagenumber = $totalpages;
|
||||
}
|
||||
|
||||
$start = ($this->pagenumber - 1) * $this->results_per_page;
|
||||
$end = $start + $this->results_per_page;
|
||||
|
||||
if ($end > $hitcount) {
|
||||
$end = $hitcount;
|
||||
if ($end > $finalresults) {
|
||||
$end = $finalresults;
|
||||
}
|
||||
} else {
|
||||
$start = 0;
|
||||
$end = $hitcount;
|
||||
}
|
||||
$end = $finalresults;
|
||||
} */
|
||||
|
||||
$resultdoc = new SearchResult();
|
||||
$resultdocs = array();
|
||||
|
||||
for ($i = $start; $i < $end; $i++) {
|
||||
for ($i = 0; $i < min($hitcount, ($page) * $this->results_per_page); $i++) {
|
||||
$hit = $hits[$i];
|
||||
|
||||
//check permissions on each result
|
||||
if ($this->can_display($USER, $hit->docid, $hit->doctype, $hit->course_id, $hit->group_id, $hit->path, $hit->itemtype, $hit->context_id )) {
|
||||
$resultdoc->number = $i;
|
||||
$resultdoc->url = $hit->url;
|
||||
$resultdoc->title = $hit->title;
|
||||
$resultdoc->score = $hit->score;
|
||||
$resultdoc->doctype = $hit->doctype;
|
||||
$resultdoc->author = $hit->author;
|
||||
|
||||
//and store it
|
||||
$resultdocs[] = clone($resultdoc);
|
||||
if ($this->can_display($USER, $hit->docid, $hit->doctype, $hit->course_id, $hit->group_id, $hit->path, $hit->itemtype, $hit->context_id, $searchables )) {
|
||||
if ($i >= ($page - 1) * $this->results_per_page){
|
||||
$resultdoc->number = $realindex;
|
||||
$resultdoc->url = $hit->url;
|
||||
$resultdoc->title = $hit->title;
|
||||
$resultdoc->score = $hit->score;
|
||||
$resultdoc->doctype = $hit->doctype;
|
||||
$resultdoc->author = $hit->author;
|
||||
$resultdoc->courseid = $hit->course_id;
|
||||
|
||||
//and store it
|
||||
$resultdocs[] = clone($resultdoc);
|
||||
}
|
||||
$realindex++;
|
||||
} else {
|
||||
// lowers total_results one unit
|
||||
$this->total_results--;
|
||||
}
|
||||
}
|
||||
|
||||
$totalpages = ceil($this->total_results/$this->results_per_page);
|
||||
|
||||
|
||||
return $resultdocs;
|
||||
}
|
||||
|
||||
@ -298,7 +309,7 @@ class SearchQuery {
|
||||
}
|
||||
} else {
|
||||
//no caching :(
|
||||
//print "Caching disabled!";
|
||||
// print "Caching disabled!";
|
||||
$resultdocs = $this->process_results();
|
||||
}
|
||||
return $resultdocs;
|
||||
@ -370,7 +381,7 @@ class SearchQuery {
|
||||
* @uses CFG
|
||||
* // TODO reorder parameters more consistently
|
||||
*/
|
||||
private function can_display(&$user, $this_id, $doctype, $course_id, $group_id, $path, $item_type, $context_id) {
|
||||
private function can_display(&$user, $this_id, $doctype, $course_id, $group_id, $path, $item_type, $context_id, &$searchables) {
|
||||
global $CFG;
|
||||
|
||||
/**
|
||||
@ -381,45 +392,50 @@ class SearchQuery {
|
||||
return true;
|
||||
}
|
||||
|
||||
// first check course compatibility against user : enrolled users to that course can see.
|
||||
$myCourses = get_my_courses($user->id);
|
||||
$unenroled = !in_array($course_id, array_keys($myCourses));
|
||||
|
||||
// if guests are allowed, logged guest can see
|
||||
$isallowedguest = (isguest()) ? get_field('course', 'guest', 'id', $course_id) : false ;
|
||||
|
||||
if ($unenroled && !$isallowedguest){
|
||||
return false;
|
||||
}
|
||||
|
||||
// if user is enrolled or is allowed user and course is hidden, can he see it ?
|
||||
$visibility = get_field('course', 'visible', 'id', $course_id);
|
||||
if ($visibility <= 0){
|
||||
if (!has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $course_id))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prerecorded capabilities
|
||||
*/
|
||||
// get context caching information and tries to discard unwanted records here
|
||||
|
||||
|
||||
/**
|
||||
* final checks
|
||||
*/
|
||||
// then give back indexing data to the module for local check
|
||||
include_once "{$CFG->dirroot}/search/documents/{$doctype}_document.php";
|
||||
$access_check_function = "{$doctype}_check_text_access";
|
||||
|
||||
if (function_exists($access_check_function)){
|
||||
$modulecheck = $access_check_function($path, $item_type, $this_id, $user, $group_id, $context_id);
|
||||
// echo "module said $modulecheck for item $doctype/$item_type/$this_id";
|
||||
return($modulecheck);
|
||||
}
|
||||
// first check course compatibility against user : enrolled users to that course can see.
|
||||
$myCourses = get_my_courses($user->id);
|
||||
$unenroled = !in_array($course_id, array_keys($myCourses));
|
||||
|
||||
return true;
|
||||
// if guests are allowed, logged guest can see
|
||||
$isallowedguest = (isguest()) ? get_field('course', 'guest', 'id', $course_id) : false ;
|
||||
|
||||
if ($unenroled && !$isallowedguest){
|
||||
return false;
|
||||
}
|
||||
|
||||
// if user is enrolled or is allowed user and course is hidden, can he see it ?
|
||||
$visibility = get_field('course', 'visible', 'id', $course_id);
|
||||
if ($visibility <= 0){
|
||||
if (!has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSE, $course_id))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prerecorded capabilities
|
||||
*/
|
||||
// get context caching information and tries to discard unwanted records here
|
||||
|
||||
|
||||
/**
|
||||
* final checks
|
||||
*/
|
||||
// then give back indexing data to the module for local check
|
||||
$searchable_instance = $searchables[$doctype];
|
||||
if ($searchable_instance->location == 'internal'){
|
||||
include_once "{$CFG->dirroot}/search/documents/{$doctype}_document.php";
|
||||
} else {
|
||||
include_once "{$CFG->dirroot}/{$searchable_instance->location}/$doctype/search_document.php";
|
||||
}
|
||||
$access_check_function = "{$doctype}_check_text_access";
|
||||
|
||||
if (function_exists($access_check_function)){
|
||||
$modulecheck = $access_check_function($path, $item_type, $this_id, $user, $group_id, $context_id);
|
||||
// echo "module said $modulecheck for item $doctype/$item_type/$this_id";
|
||||
return($modulecheck);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
33
search/searchtypes.php
Normal file
33
search/searchtypes.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [cynnical@gmail.com], Valery Fremaux [valery.fremaux@club-internet.fr] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Searcheable types
|
||||
* to disable a type, just comment the two declaration lines for that type
|
||||
*
|
||||
*/
|
||||
|
||||
//document types that can be searched
|
||||
//define('SEARCH_TYPE_NONE', 'none');
|
||||
define('SEARCH_TYPE_WIKI', 'wiki');
|
||||
define('SEARCH_TYPE_FORUM', 'forum');
|
||||
define('SEARCH_TYPE_GLOSSARY', 'glossary');
|
||||
define('SEARCH_TYPE_RESOURCE', 'resource');
|
||||
define('SEARCH_TYPE_DATA', 'data');
|
||||
define('SEARCH_TYPE_CHAT', 'chat');
|
||||
define('SEARCH_TYPE_LESSON', 'lesson');
|
||||
define('SEARCH_TYPE_ASSIGNMENT', 'assignment');
|
||||
|
||||
define('SEARCH_EXTRAS', 'user');
|
||||
define('SEARCH_TYPE_USER', 'user');
|
||||
define('PATH_FOR_SEARCH_TYPE_USER', 'user');
|
||||
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user