Browse Source

[svn r16096] Integration of search feature into Oogie

Yannick Warnier 16 years ago
parent
commit
ed02440974

BIN
main/inc/lib/ppt2png/OogieDocumentConverter.class


+ 17 - 5
main/inc/lib/ppt2png/OogieDocumentConverter.java

@@ -114,23 +114,35 @@ public class OogieDocumentConverter extends AbstractDokeosDocumentConverter {
 				XDrawPage page = (XDrawPage) UnoRuntime.queryInterface(
 						com.sun.star.drawing.XDrawPage.class, pages
 								.getByIndex(i));
+				// get all the page shapes
 				XShapes xShapes = (XShapes)UnoRuntime.queryInterface(XShapes.class, page);
 				int top = 0;
 				String slidename = "";
+				String slidebody = "";
+				String shapetext = "";
 				for (int j = 0; j < xShapes.getCount(); j++) {
 					XShape firstXshape = (XShape)UnoRuntime.queryInterface(XShape.class, xShapes.getByIndex(j));
 					Point pos = firstXshape.getPosition();
-					if(pos.Y < top || top==0)
+
+					XText xText = (XText)UnoRuntime.queryInterface( XText.class, firstXshape );
+					if(xText!=null && xText.getString().length()>0)
 					{
-						XText xText = (XText)UnoRuntime.queryInterface( XText.class, firstXshape );
-						if(xText!=null && xText.getString().length()>0)
+						shapetext = xText.getString();
+						// concatening all shape texts to later use
+						slidebody += " " + shapetext;
+
+						// get the top shape
+						if(pos.Y < top || top==0)
 						{
 							top = pos.Y;
-							slidename = xText.getString();
+							slidename = shapetext;
 						}
 					}
 				}
 
+				// remove unwanted chars
+				slidebody = slidebody.replaceAll("\n", " ");
+
 				String slidenameDisplayed = "";
 				if(slidename.trim().length()==0)
 				{
@@ -213,7 +225,7 @@ public class OogieDocumentConverter extends AbstractDokeosDocumentConverter {
 				xFilter.filter(loadProps);
 				if(slidenameDisplayed=="")
 					slidenameDisplayed = xPageName.getName();
-				System.out.println(slidenameDisplayed+"||"+xPageName.getName()+".png");
+				System.out.println(slidenameDisplayed+"||"+xPageName.getName()+".png"+"||"+slidebody);
 				
 			}
 			

+ 35 - 4
main/newscorm/learnpath.class.php

@@ -865,16 +865,27 @@ class learnpath {
     	$res_upd = api_sql_query($sql_upd,__FILE__,__LINE__);
     	//now update all following items with new display order
     	$sql_all = "UPDATE $lp_item SET display_order = display_order-1 WHERE lp_id = $lp AND parent_item_id = $parent AND display_order > $display";
-    	$res_all = api_sql_query($sql_all,__FILE__,__LINE__);
+        $res_all = api_sql_query($sql_all,__FILE__,__LINE__);
+        // remove from search engine if enabled
+        if (api_get_setting('search_enabled') == 'true') {
+          require_once(api_get_path(LIBRARY_PATH) .'search/DokeosIndexer.class.php');
+          $di = new DokeosIndexer();
+          $di->remove_document($row['search_did']);
+        }
     }
 
     /**
      * Updates an item's content in place
      * @param	integer	Element ID
-	 * @param	string	New content
+	 * @param	integer	Parent item ID
+	 * @param	integer Previous item ID
+	 * @param   string	Item title
+	 * @param   string  Item description
+	 * @param   string  Prerequisites (optional)
+	 * @param   string  Indexing terms (optional)
      * @return	boolean	True on success, false on error
      */
-    function edit_item($id, $parent, $previous, $title, $description, $prerequisites=0)
+    function edit_item($id, $parent, $previous, $title, $description, $prerequisites=0, $terms=NULL)
     {
     	if($this->debug > 0){error_log('New LP - In learnpath::edit_item()', 0);}
 
@@ -889,6 +900,19 @@ class learnpath {
     	$res_select = api_sql_query($sql_select, __FILE__, __LINE__);
     	$row_select = Database::fetch_array($res_select);
     	
+        $terms_update_sql='';
+        if (!is_null($terms)) {
+          //TODO: validate csv string
+          $terms_update_sql = ", terms = '". $this->escape_string(htmlentities($terms)) . "'";
+
+          // save it to search engine
+          if (api_get_setting('search_enabled') == 'true') {
+            require_once(api_get_path(LIBRARY_PATH).'search/DokeosIndexer.class.php');
+            $di = new DokeosIndexer();
+            $di->update_terms($row_select['search_did'], explode(',', $terms));
+          }
+        }
+
     	$same_parent	= ($row_select['parent_item_id'] == $parent) ? true : false;
     	$same_previous	= ($row_select['previous_item_id'] == $previous) ? true : false;
     	
@@ -901,6 +925,7 @@ class learnpath {
     				title = '" . $this->escape_string(htmlentities($title)) . "',
 					prerequisite = '".$prerequisites."',
     				description = '" . $this->escape_string(htmlentities($description)) . "'
+                    ". $terms_update_sql . "
     			WHERE id = " . $id;
     		$res_update = api_sql_query($sql_update, __FILE__, __LINE__);
     	}
@@ -1018,6 +1043,7 @@ class learnpath {
 	    			previous_item_id = " . $previous . ",
 	    			next_item_id = " . $new_next . ",
 	    			display_order = " . $new_order . "
+                    ". $terms_update_sql . "	
 	    		WHERE id = " . $id;
     		$res_update_next = api_sql_query($sql_update, __FILE__, __LINE__);
     		//echo '<p>' . $sql_update . '</p>';
@@ -6003,6 +6029,7 @@ class learnpath {
 		{
 			$item_title			= stripslashes($extra_info['title']);
 			$item_description	= stripslashes($extra_info['description']);	
+            $item_terms         = stripslashes($extra_info['terms']);        
 			if(empty($item_title))
 			{				
 				$path_parts = pathinfo($extra_info['path']);
@@ -6210,7 +6237,11 @@ class learnpath {
 
 				$select_prerequisites=$form->addElement('select', 'prerequisites', get_lang('Prerequisites').'&nbsp;:', '', 'id="prerequisites" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:300px;"');
 				$select_prerequisites->addOption(get_lang("NoPrerequisites"),0,'style="padding-left:3px;"');
-				
+
+                //add terms field
+                $terms = $form->addElement('text','terms', get_lang('SearchFeatureTerms').'&nbsp;:','id="idTerms" style="background:#F8F8F8; border:1px solid #999999; font-family:Arial, Verdana, Helvetica, sans-serif; font-size:12px; width:295px;"');
+                $terms->setValue($item_terms); 
+
 				$arrHide=array();
 
 				for($i = 0; $i < count($arrLP); $i++)

+ 7 - 1
main/newscorm/lp_controller.php

@@ -366,7 +366,7 @@ switch($action)
 			
 			if(isset($_POST['submit_button']) && !empty($_POST['title']))
 			{
-				$_SESSION['oLP']->edit_item($_GET['id'], $_POST['parent'], $_POST['previous'], $_POST['title'], $_POST['description'], $_POST['prerequisites']);
+				$_SESSION['oLP']->edit_item($_GET['id'], $_POST['parent'], $_POST['previous'], $_POST['title'], $_POST['description'], $_POST['prerequisites'], $_POST['terms']);
 				
 				if(isset($_POST['content_lp']))
 				{
@@ -803,6 +803,12 @@ switch($action)
             header('location: ../course_home/course_home.php?'.api_get_cidreq());
         }
         break;        
+    case 'search':
+        /* Include the search script, it's smart enough to know when we are
+         * searching or not
+         */
+        require 'lp_list_search.php';
+        break;
 	default:
 		if($debug>0) error_log('New LP - default action triggered',0);
 		//$_SESSION['refresh'] = 1;

+ 10 - 0
main/newscorm/lp_list.php

@@ -73,6 +73,11 @@ if (! $is_allowed_in_course) api_not_allowed();
 /**
  * Display
  */
+/* Require the search widget and prepare the header with its stuff */
+if (api_get_setting('search_enabled') == 'true') {
+  require api_get_path(LIBRARY_PATH).'search/search_widget.php';
+  search_widget_prepare(&$htmlHeadXtra);
+}
 Display::display_header($nameTools,"Path");
 //api_display_tool_title($nameTools);
 
@@ -385,6 +390,11 @@ if (is_array($flat_list))
 }// end if ( is_array($flat_list)
 echo "</table>";
 echo "<br/><br/>";
+
+/* search widget */
+if (api_get_setting('search_enabled') == 'true')
+    search_widget_show();
+
 /*
 ==============================================================================
   FOOTER

+ 195 - 0
main/newscorm/lp_list_search.php

@@ -0,0 +1,195 @@
+<?php
+/*
+ * Script to draw the results from a query
+ * @package: dokeos.learnpath
+ * @author: Diego Escalante Urrelo <diegoe@gmail.com>
+ */
+require api_get_path(LIBRARY_PATH).'search/search_widget.php';
+require api_get_path(LIBRARY_PATH).'search/DokeosQuery.php';
+
+
+$htmlHeadXtra[] = '
+    <style type="text/css">
+    .doc_table {
+        width: 30%;
+        text-align: left;
+    }
+    .doc_img {
+        border: 1px solid black;
+        padding: 1px solid white;
+        background: white;
+    }
+    .doc_img,
+    .doc_img img {
+        width: 120px;
+    }
+    .doc_text, 
+    .doc_title {
+        padding-left: 10px;
+        vertical-align: top;
+    }
+    .doc_title {
+        font-size: large;
+        font-weight: bold;
+        height: 2em;
+    }
+    </style>';
+
+
+search_widget_prepare(&$htmlHeadXtra);
+
+Display::display_header(null,'Path');
+
+if (api_get_setting('search_enabled') === 'true') {
+    Display::display_error_message(get_lang("
+    Search is not enabled in Dokeos. Contact your administrator.
+    "));
+    Display::display_footer();
+}
+/* else... */
+search_widget_show();
+
+
+/**
+ * Utility function to get a table for a specific course.
+ * 
+ * @param   string $course_code     The course_code as in cidReq 
+ * @param   string $table           The desired table, this is just concat'd.
+ * @return  string 
+ */
+function get_course_table($course_code, $table) {
+    $ret = NULL;
+
+    $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
+    $course_cat_table = Database::get_main_table(TABLE_MAIN_CATEGORY);
+    $sql = "SELECT 
+                `course`.`db_name`, `course_category`.`code`
+            FROM $course_table
+            LEFT JOIN $course_cat_table
+            ON 
+                `course`.`category_code` =  `course_category`.`code`
+            WHERE 
+                `course`.`code` = '$course_code'
+            LIMIT 1";
+    $res = api_sql_query($sql, __FILE__, __LINE__);
+    $result = Database::fetch_array($res);
+
+    $ret = sprintf ("%s.%s",
+        $result[0],
+        $table);
+
+    return $ret;
+}
+
+$tags = explode(",", trim($_REQUEST['tags']));
+$tags2 = '';
+
+foreach ($tags as $tag)
+    if (strlen($tag)> 1)
+        $tags2 .= " tag:".trim($tag);
+
+$query = $_REQUEST['query'] . ' ' . $tags2;
+
+$query_results = dokeos_query_query($query, 0, 1000);
+$count = $query_results[0];
+$results = $query_results[1];
+
+$blocks = array();
+
+$url = api_get_path(WEB_CODE_PATH)."/newscorm/lp_controller.php";
+
+$search_url = sprintf('%s?action=search&query=%s&tags=%s', 
+                $url, $_REQUEST['query'], $_REQUEST['tags']);
+
+$link_format = $url.'?cidReq=%s&action=view&lp_id=%s&item_id=%s';
+
+if ($count > 0) {
+    foreach ($results as $result) {
+        /* FIXME:diegoe: marco debe darme los valores adecuados. */
+        $ids = explode(":", $result->ids);
+        $course_id = $ids[0];
+        $lp_id = $ids[1];
+        $doc_id = $ids[2];
+
+        if (!api_is_course_visible_for_user(NULL, $course_id))
+            continue;
+
+        $tags = '';
+        foreach ($result->terms as $term) {
+            $tags .= trim($term['name'], 'T') . ", ";
+        }
+
+        
+        $lp_table = get_course_table($course_id, TABLE_LP_ITEM);
+        $doc_table = get_course_table($course_id, TABLE_DOCUMENT);
+        $sql = "SELECT 
+                    $doc_table.title, $doc_table.path, $lp_table.id
+                FROM $lp_table INNER JOIN $doc_table 
+                    ON $lp_table.path = $doc_table.id  
+                    WHERE 
+                        $lp_table.lp_id = $lp_id 
+                    AND 
+                        $doc_table.id = $doc_id 
+                LIMIT 1";
+
+        $dk_result = api_sql_query ($sql);
+
+        while ($row = Database::fetch_array ($dk_result)) {
+            /* Get the image path */
+            $img_path = str_replace ('.png.html', '_thumb.png', $row['path']);
+            $doc_id = $row['id'];
+            $title = $row['title'];
+
+            $href = sprintf($link_format, $course_id, $lp_id, $doc_id);
+
+            /* Fill the result array */
+            $blocks[] = array(
+                api_get_path(WEB_COURSE_PATH).api_get_course_path($course_id)."/document/".$img_path, 
+                $title, 
+                $tags,
+                $href
+                );
+        }
+    }
+}
+
+if (count($blocks) < 1) {
+    Display::display_normal_message(get_lang("
+    To search the learning path db, use the following syntax:<br/>
+    &nbsp;&nbsp;&nbsp;<i>term tag:tag_name -exclude +include \"exact phrase\"</i><br/>
+    For example:<br/>
+    &nbsp;&nbsp;&nbsp;<i>car tag:truck -ferrari +ford \"high consume\".</i><br/>
+    This will show all the results for the word 'car' tagged as 'truck', not
+    including the word 'ferrari' but including the word 'ford' and the exact
+    phrase 'high consume'.
+    "), FALSE);
+}
+else
+{
+?>
+
+<?php
+function to_img($i) {
+    return sprintf('<img src="%s"/>', $i);
+}
+function to_link($i) {
+    return sprintf('<a href="%s">%s</a>', $i, get_lang("View learning path"));
+}
+
+    $s = new SortableTableFromArray($blocks);
+    $s->additional_parameters = array(
+                'action' => 'search',
+                'query' => $_REQUEST['query'],
+                'tags' => $_REQUEST['tags'],
+                );
+    $s->set_header(0, get_lang('Preview'));
+    $s->set_header(1, get_lang('Title'));
+    $s->set_header(2, get_lang('Tags'));
+    $s->set_header(3, get_lang('Learning path'));
+    $s->set_column_filter(0,'to_img');
+    $s->set_column_filter(3,'to_link');
+    $s->display();
+}
+
+Display::display_footer();
+?>

+ 59 - 2
main/newscorm/openoffice_presentation.class.php

@@ -12,6 +12,8 @@
  * @package dokeos.learnpath.openofficedocument
  */
 require_once('openoffice_document.class.php');
+require_once(api_get_path(LIBRARY_PATH).'search/DokeosIndexer.class.php');
+require_once(api_get_path(LIBRARY_PATH).'search/IndexableChunk.class.php');
 
 class OpenofficePresentation extends OpenofficeDocument {
 	
@@ -38,7 +40,7 @@ class OpenofficePresentation extends OpenofficeDocument {
 		
 		foreach($files as $file){
 			
-			list($slide_name,$file_name) = explode('||',$file); // '||' is used as separator between slide name (with accents) and file name (without accents)
+			list($slide_name,$file_name,$slide_body) = explode('||',$file); // '||' is used as separator between fields: slide name (with accents) || file name (without accents) || all slide text (to be indexed)
 			
 			//filename is utf8 encoded, but when we decode, some chars are not translated (like quote &rsquo;).
 			//so we remove these chars by translating it in htmlentities and the reconvert it in want charset
@@ -61,7 +63,26 @@ class OpenofficePresentation extends OpenofficeDocument {
 			// add the png to documents
 			$document_id = add_document($_course,$this->created_dir.'/'.urlencode($file_name),'file',filesize($this->base_work_dir.$this->created_dir.'/'.$file_name),$slide_name);
 			api_item_property_update($_course,TOOL_DOCUMENT,$document_id,'DocumentAdded',api_get_user_id(),0,0);
-			
+
+            // Generating the thumbnail
+            $image = $this->base_work_dir.$this->created_dir .'/'. $file_name;
+            // calculate thumbnail size
+            list($width, $height) = getimagesize($image);
+            $thumb_width = 200;
+            $thumb_height = floor( $height * ($thumb_width / $width ) );
+            // load
+            $thumb = imagecreatetruecolor($thumb_width, $thumb_height);
+            $source = imagecreatefrompng($image);
+            // resize
+            imagecopyresized($thumb, $source, 0, 0, 0, 0, $thumb_width, $thumb_height, $width, $height);
+            // output
+            $pattern = '/(\w+)\.png$/';
+            $replacement = '${1}_thumb.png';
+            $thumb_name = preg_replace($pattern, $replacement, $file_name);
+            imagepng($thumb, $this->base_work_dir.$this->created_dir .'/'. $thumb_name);
+            // adding the thumbnail to documents
+            $document_id_thumb = add_document($_course, $this->created_dir.'/'.urlencode($thumb_name), 'file', filesize($this->base_work_dir.$this->created_dir.'/'.$thumb_name), $slide_name);
+            api_item_property_update($_course, TOOL_THUMBNAIL, $document_id_thumb,'DocumentAdded',api_get_user_id(),0,0);
 			
 			// create an html file
 			$html_file = $file_name.'.html';
@@ -86,6 +107,42 @@ class OpenofficePresentation extends OpenofficeDocument {
 					$this->first_item = $previous;
 				}
 			}
+            // code for text indexing
+            if (isset($_POST['index_document']) && $_POST['index_document']) {
+              //Display::display_normal_message(print_r($_POST));
+              $di = new DokeosIndexer();
+              isset($_POST['language'])? $lang=Database::escape_string($_POST['language']): $lang = 'english';
+              $di->connectDb(NULL, NULL, $lang);
+              $ic_slide = new IndexableChunk();
+              $ic_slide->addValue("title", $slide_name);
+              if (isset($_POST['terms'])) {
+                foreach (explode(',', Database::escape_string($_POST['terms'])) as $term){
+                  $ic_slide->addTerm(trim($term),'T');
+                }
+              }
+              $ic_slide->addValue("content", $slide_body);
+              /* FIXME:  cidReq:lp_id:doc_id al indexar  */
+              //       add a comment to say terms separated by commas
+              $courseid=api_get_course_id();
+              $ic_slide->addTerm($courseid,'C');
+              //TODO: add dokeos tool type instead of filetype
+              $lp_id = $this->lp_id;
+              // TODO: get "path" field
+              $ic_slide->addValue('ids', $courseid .':'. $this->lp_id
+              .':'.$document_id );
+              $di->addChunk($ic_slide);
+              //index and return search engine document id
+              $did = $di->index();
+              if ($did) {
+                // save it to db
+                $tbl_lp_item = Database::get_course_table('lp_item');
+                $sql_update = "
+                  UPDATE " . $tbl_lp_item . "
+                  SET search_did = " . $did . "
+                  WHERE id = " . $previous;
+                api_sql_query($sql_update, __FILE__, __LINE__);
+              }
+            }
 		}
     }
     

+ 6 - 0
main/upload/upload_ppt.php

@@ -164,6 +164,12 @@ $renderer->setElementTemplate($user_file_template);
 
 $form -> addElement ('file', 'user_file','<img src="../img/powerpoint_big.gif" align="absbottom" />&nbsp;&nbsp;');
 $form -> addElement ('checkbox', 'take_slide_name','', get_lang('TakeSlideName'));
+if(api_get_setting('search_enabled')=='true')
+{
+  $form -> addElement ('checkbox', 'index_document','', get_lang('SearchFeatureDoIndexDocument'));
+  $form -> addElement ('text', 'terms', get_lang('SearchFeatureDocumentTagsIfIndexing'));
+  $form -> addElement ('html', get_lang('SearchFeatureDocumentLanguage').': '. api_get_languages_combo()); 
+}
 $form -> addElement ('submit', 'convert', get_lang('ConvertToLP'), 'class="convert_button"');
 
 $form -> addElement ('hidden', 'ppt2lp', 'true');