]> git.mjollnir.org Git - moodle.git/commitdiff
fixes result list ordering issue
authordiml <diml>
Sat, 31 May 2008 15:17:28 +0000 (15:17 +0000)
committerdiml <diml>
Sat, 31 May 2008 15:17:28 +0000 (15:17 +0000)
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

search/lib.php
search/query.php
search/querylib.php
search/searchtypes.php [new file with mode: 0644]

index 9a5f23ac761877753d81744cf0a7bd16c2b95e8c..638fea885ea7fc26757c9224d33e850769e955b2 100644 (file)
@@ -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
index b9024166e7925eb8f26999358f835e24e1364615..e8affc712cc65691183792eff2d72eb2ad2ba40e 100644 (file)
@@ -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
             $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);
     } 
     <?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();
         
             $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();
     ?>
index 3683628f50e0681aa954b512cdab0482b239a2c3..7db4eef9ab43a1cbab1cefd79b091e4b88899887 100644 (file)
@@ -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));
+        
+        // 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";
         
-      return true;
+        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;
     }
 
     /**
diff --git a/search/searchtypes.php b/search/searchtypes.php
new file mode 100644 (file)
index 0000000..16f1a5c
--- /dev/null
@@ -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');
+
+?>
\ No newline at end of file