diff --git a/main/inc/lib/ppt2png/OogieDocumentConverter.class b/main/inc/lib/ppt2png/OogieDocumentConverter.class index 0e08e25af3..0e28cbbbef 100644 Binary files a/main/inc/lib/ppt2png/OogieDocumentConverter.class and b/main/inc/lib/ppt2png/OogieDocumentConverter.class differ diff --git a/main/inc/lib/ppt2png/OogieDocumentConverter.java b/main/inc/lib/ppt2png/OogieDocumentConverter.java index bd3ebf5100..3b51d8fe83 100644 --- a/main/inc/lib/ppt2png/OogieDocumentConverter.java +++ b/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); } diff --git a/main/newscorm/learnpath.class.php b/main/newscorm/learnpath.class.php index 47292d541b..993f9f8419 100644 --- a/main/newscorm/learnpath.class.php +++ b/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 '

' . $sql_update . '

'; @@ -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').' :', '', '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').' :','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++) diff --git a/main/newscorm/lp_controller.php b/main/newscorm/lp_controller.php index 2fad00036f..f4ff77d9d6 100644 --- a/main/newscorm/lp_controller.php +++ b/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; diff --git a/main/newscorm/lp_list.php b/main/newscorm/lp_list.php index 4a157ae3ac..36f7eecbf6 100644 --- a/main/newscorm/lp_list.php +++ b/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 ""; echo "

"; + +/* search widget */ +if (api_get_setting('search_enabled') == 'true') + search_widget_show(); + /* ============================================================================== FOOTER diff --git a/main/newscorm/lp_list_search.php b/main/newscorm/lp_list_search.php new file mode 100644 index 0000000000..15154c9c5b --- /dev/null +++ b/main/newscorm/lp_list_search.php @@ -0,0 +1,195 @@ + + */ +require api_get_path(LIBRARY_PATH).'search/search_widget.php'; +require api_get_path(LIBRARY_PATH).'search/DokeosQuery.php'; + + +$htmlHeadXtra[] = ' + '; + + +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:
+    term tag:tag_name -exclude +include \"exact phrase\"
+ For example:
+    car tag:truck -ferrari +ford \"high consume\".
+ 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 +{ +?> + +', $i); +} +function to_link($i) { + return sprintf('%s', $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(); +?> diff --git a/main/newscorm/openoffice_presentation.class.php b/main/newscorm/openoffice_presentation.class.php index ea74364ab8..190cca4268 100644 --- a/main/newscorm/openoffice_presentation.class.php +++ b/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 ’). //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__); + } + } } } diff --git a/main/upload/upload_ppt.php b/main/upload/upload_ppt.php index f70014ec75..0ea98bcd4e 100644 --- a/main/upload/upload_ppt.php +++ b/main/upload/upload_ppt.php @@ -164,6 +164,12 @@ $renderer->setElementTemplate($user_file_template); $form -> addElement ('file', 'user_file','  '); $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');