Browse Source

added thematic advance inside course description tool, making mvc model - partial CT#577

Cristian Fasanando 15 years ago
parent
commit
23b2a97adf

+ 77 - 0
main/course_description/add.php

@@ -0,0 +1,77 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+* View (MVC patter) for adding a course description 
+* @package dokeos.course_description
+* @author Christian Fasanando <christian1827@gmail.com>
+*/
+
+api_protect_course_script(true);
+
+// display categories
+$categories = array ();
+foreach ($default_description_titles as $id => $title) {
+	$categories[$id] = $title;
+}
+$categories[ADD_BLOCK] = get_lang('NewBloc');
+
+$i=1;
+echo '<div class="actions" style="margin-bottom:30px">';
+ksort($categories);
+foreach ($categories as $id => $title) {
+	if ($i==ADD_BLOCK) {
+		echo '<a href="index.php?'.api_get_cidreq().'&action=add">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>';
+		break;
+	} else {
+		echo '<a href="index.php?action=edit&'.api_get_cidreq().'&description_type='.$id.'">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>&nbsp;&nbsp;';
+		$i++;
+	}
+}
+echo '</div>';
+
+// error messages
+if (isset($error) && intval($error) == 1) {	
+	Display::display_error_message(get_lang('FormHasErrorsPleaseComplete'),false);	
+}
+
+// default header title form
+$header = '';
+$description_type = intval($description_type);
+if ($description_type >= ADD_BLOCK) {
+	$header = $default_description_titles[ADD_BLOCK];
+}
+
+$token = Security::get_token();
+// display form
+$form = new FormValidator('course_description','POST','index.php?action=add&'.api_get_cidreq(),'','style="width: 100%;"');
+$form->addElement('header', '', $header);
+$form->addElement('hidden', 'description_type',$description_type);
+$form->addElement('hidden', 'sec_token',$token);
+$form->add_textfield('title', get_lang('Title'), true, array('size'=>'width: 350px;'));
+$form->applyFilter('title','html_filter');
+
+if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+	WCAG_rendering::prepare_admin_form($description_content, $form);
+} else {
+	$form->add_html_editor('contentDescription', get_lang('Content'), true, false, array('ToolbarSet' => 'TrainingDescription', 'Width' => '100%', 'Height' => '200'));
+}
+$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
+
+// display default questions			
+if (isset ($question[$description_type])) {
+	$message = '<strong>'.get_lang('QuestionPlan').'</strong><br />';
+	$message .= $question[$description_type];
+	Display::display_normal_message($message, false);
+}
+
+if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+	echo (WCAG_Rendering::editor_header());
+}
+
+$form->display();
+
+if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+	echo (WCAG_Rendering::editor_footer());
+}
+?>

+ 233 - 0
main/course_description/course_description_controller.php

@@ -0,0 +1,233 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+ * Controller script. Prepares the common background variables to give to the scripts corresponding to
+ * the requested action
+ * @package dokeos.course_description
+ * @author Christian Fasanando <christian1827@gmail.com>
+ */
+
+class CourseDescriptionController { // extends Controller {	
+		
+	private $toolname;
+	private $view; 
+	
+	/**
+	 * Constructor
+	 */
+	public function __construct() {		
+		$this->toolname = 'course_description';	
+		$this->view = new View($this->toolname);			
+	}
+
+	/**
+	 * It's used for listing course description,
+	 * render to listing view
+	 * @param boolan   	true for listing history (optional)
+	 * @param array 	message for showing by action['edit','add','destroy'] (optional) 
+	 */
+	public function listing($history=false,$messages=array()) {
+		$course_description = new CourseDescription();
+		$session_id = api_get_session_id();
+		$course_description->set_session_id($session_id);        
+		$data = array();		
+
+		if ($history) {
+			$course_description_data = $course_description->get_description_history(THEMATIC_ADVANCE);	
+			$data['history'] = true;		
+		} else {
+			$course_description_data = $course_description->get_description_data();	
+		}
+		
+		$data['descriptions'] = $course_description_data['descriptions'];
+		$data['default_description_titles'] = $course_description->get_default_description_title();
+		$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
+		$data['default_description_icon'] = $course_description->get_default_description_icon();		
+		$data['messages'] = $messages;
+		
+		// render to the view
+		$this->view->set_data($data);
+		$this->view->set_layout('layout'); 
+		$this->view->set_template('listing');		       
+		$this->view->render();				
+	}
+	
+	/**
+	 * It's used for editing a course description,
+	 * render to listing or edit view
+	 * @param int description type
+	 */
+	public function edit($description_type) {
+		$course_description = new CourseDescription();
+		$session_id = api_get_session_id();
+		$course_description->set_session_id($session_id);		
+		$data = array();            
+        if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") {        	
+        	if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) {
+        		
+        		$check = Security::check_token();        		
+        		if ($check) {
+        			$title = $_POST['title'];
+		        	if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+						$content = WCAG_Rendering::prepareXHTML();
+					} else {
+						$content = $_POST['contentDescription'];
+					}        	
+		        	$description_type = $_POST['description_type'];
+		        	$progress		  = $_POST['progress'];
+					$course_description->set_description_type($description_type);
+		    		$course_description->set_title($title);
+		    		$course_description->set_content($content);
+		    		$course_description->set_progress($progress);		
+		        	if ($description_type >= ADD_BLOCK) {        		        		
+						$affected_rows = $course_description->update();
+		        	} else {	        			        		
+		        		$thematic_advance = $course_description->get_data_by_description_type($description_type);	        		
+		        		if (!empty($thematic_advance)) {
+		        			if ($description_type == THEMATIC_ADVANCE) {
+		        				// if is thematic advance type save in history
+		        				$course_description->set_title($thematic_advance['description_title']);
+		        				$course_description->set_content($thematic_advance['description_content']);
+		        				$course_description->insert_stats($description_type);
+		        			}
+		        			$course_description->set_title($title);
+		        			$course_description->set_content($content);	        			
+		        			$affected_rows = $course_description->update();	        			
+		        		} else {
+		        			$affected_rows = $course_description->insert();
+		        		}	        		
+		        	}
+		        	Security::clear_token();		        		        		
+        		}
+        		
+        		if ($affected_rows) {        			
+					$message['edit'] = true;        			
+				}
+				$this->listing(false,$message);		        		        		
+        		      		
+        	} else {
+        		$data['error'] = 1;
+        		$data['default_description_titles'] = $course_description->get_default_description_title();
+				$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
+				$data['default_description_icon'] = $course_description->get_default_description_icon();
+				$data['question'] = $course_description->get_default_question();
+				$data['information'] = $course_description->get_default_information();
+        		$data['description_title'] = $_POST['title'];
+        		$data['description_content'] = $_POST['contentDescription'];
+        		$data['description_type'] = $_POST['description_type'];
+        		$data['progress'] = $_POST['progress'];
+        		$data['descriptions'] = $course_description->get_data_by_description_type($_POST['description_type']);
+        		// render to the view
+				$this->view->set_data($data);
+				$this->view->set_layout('layout');
+				$this->view->set_template('edit');			        
+				$this->view->render();        		
+        	}
+        } else {
+			if (!empty($description_type)) {							
+        		$course_description_data = $course_description->get_data_by_description_type($description_type);        		
+        		$data['default_description_titles'] = $course_description->get_default_description_title();
+				$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
+				$data['default_description_icon'] = $course_description->get_default_description_icon();
+				$data['question'] = $course_description->get_default_question();
+				$data['information'] = $course_description->get_default_information();
+				$data['description_title'] = $course_description_data['description_title'];
+        		$data['description_content'] = $course_description_data['description_content'];
+        		$data['description_type'] = $description_type;
+        		$data['progress'] = $course_description_data['progress'];
+        		$data['descriptions'] = $course_description->get_data_by_description_type($description_type);
+        	}
+        	// render to the view        					
+			$this->view->set_data($data);
+			$this->view->set_layout('layout');
+			$this->view->set_template('edit');			        
+			$this->view->render();        	
+        }
+	}
+	
+	/**
+	 * It's used for adding a course description,
+	 * render to listing or add view
+	 */
+	public function add() {
+		$course_description = new CourseDescription();
+		$session_id = api_get_session_id();
+		$course_description->set_session_id($session_id);
+		
+		$data = array();            
+        if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") {        	
+        	if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) {
+        		
+        		$check = Security::check_token();        		
+        		if ($check) {
+        			$title = $_POST['title'];
+		        	if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+						$content = WCAG_Rendering::prepareXHTML();
+					} else {
+						$content = $_POST['contentDescription'];
+					}        	
+		        	$description_type = $_POST['description_type'];	
+		        	if ($description_type >= ADD_BLOCK) {        		
+		        		$course_description->set_description_type($description_type);
+		        		$course_description->set_title($title);
+		        		$course_description->set_content($content);
+						$affected_rows = $course_description->insert();
+		        	}
+		        	Security::clear_token();	
+        		} 
+        		if ($affected_rows) {        			
+					$message['add'] = true;        			
+				}
+				$this->listing(false,$message);	        			
+        	} else {
+        		$data['error'] = 1;
+        		$data['default_description_titles'] = $course_description->get_default_description_title();
+				$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
+				$data['default_description_icon'] = $course_description->get_default_description_icon();
+				$data['question'] = $course_description->get_default_question();
+				$data['information'] = $course_description->get_default_information();
+        		$data['description_title'] = $_POST['title'];
+        		$data['description_content'] = $_POST['contentDescription'];
+        		$data['description_type'] = $_POST['description_type'];        		
+				$this->view->set_data($data);
+				$this->view->set_layout('layout');
+				$this->view->set_template('add');			        
+				$this->view->render();
+        	}        	        
+        } else {											
+			$data['default_description_titles'] = $course_description->get_default_description_title();
+			$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
+			$data['default_description_icon'] = $course_description->get_default_description_icon();
+			$data['question'] = $course_description->get_default_question();
+			$data['information'] = $course_description->get_default_information();
+			$data['description_type'] = $course_description->get_max_description_type(); 				
+			// render to the view
+			$this->view->set_data($data);
+			$this->view->set_layout('layout'); 
+			$this->view->set_template('add');			       
+			$this->view->render(); 	
+        }
+	}
+	
+	/**
+	 * It's used for destroy a course description,
+	 * render to listing view
+	 * @param int description type
+	 */
+	public function destroy($description_type) {		
+		$course_description = new CourseDescription();
+		$session_id = api_get_session_id();
+		$course_description->set_session_id($session_id);		
+		if (!empty($description_type)) {
+			$course_description->set_description_type($description_type);
+			$affected_rows = $course_description->delete();
+		}		
+		if ($affected_rows) {        			
+			$message['destroy'] = true;        			
+		}
+		$this->listing(false,$message);		
+	}
+
+}
+?>

+ 98 - 0
main/course_description/edit.php

@@ -0,0 +1,98 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+* View (MVC patter) for editing a course description 
+* @package dokeos.course_description
+* @author Christian Fasanando <christian1827@gmail.com>
+*/
+
+api_protect_course_script(true);
+
+$token = Security::get_token();
+
+// display categories
+$categories = array ();
+foreach ($default_description_titles as $id => $title) {
+	$categories[$id] = $title;
+}
+$categories[ADD_BLOCK] = get_lang('NewBloc');
+
+$i=1;
+echo '<div class="actions" style="margin-bottom:30px">';
+ksort($categories);
+foreach ($categories as $id => $title) {
+	if ($i==ADD_BLOCK) {
+		echo '<a href="index?'.api_get_cidreq().'&action=add">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>';
+		break;
+	} else {
+		echo '<a href="index.php?action=edit&'.api_get_cidreq().'&description_type='.$id.'">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>&nbsp;&nbsp;';
+		$i++;
+	}
+}
+echo '</div>';
+
+// error messages
+if (isset($error) && intval($error) == 1) {	
+	Display::display_error_message(get_lang('FormHasErrorsPleaseComplete'),false);	
+}
+
+// default header title form
+$description_type = intval($description_type);
+$header = $default_description_titles[$description_type];
+if ($description_type >= ADD_BLOCK) {
+	$header = $default_description_titles[ADD_BLOCK];
+}
+
+// display form
+$form = new FormValidator('course_description','POST','index.php?action=edit&description_type='.$description_type.'&'.api_get_cidreq(),'','style="width: 100%;"');
+if ($description_type == THEMATIC_ADVANCE) {
+	$form->addElement('html','<div class="row">
+						  <div class="form_header"><table width="100%"><tr><td>'.get_lang('ThematicAdvance').'</td><td align="right"><a href="index?action=history&description_type='.$description_type.'">'.Display::return_icon('lp_dir.png',get_lang('ThematicAdvanceHistory'),array('style'=>'vertical-align:middle;hspace:6')).' '.get_lang('ThematicAdvanceHistory').'</a></td></tr></table>						  
+						  </div>');
+} else {
+	$form->addElement('header','',$header);
+}
+$form->addElement('hidden', 'description_type',$description_type);
+$form->addElement('hidden', 'sec_token',$token);
+$form->add_textfield('title', get_lang('Title'), true, array('size'=>'50'));
+$form->applyFilter('title','html_filter');
+
+if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+	WCAG_rendering::prepare_admin_form($description_content, $form);
+} else {
+	$form->add_html_editor('contentDescription', get_lang('Content'), true, false, array('ToolbarSet' => 'TrainingDescription', 'Width' => '100%', 'Height' => '200'));
+}
+
+if ($description_type == THEMATIC_ADVANCE) {
+	$options_select = array(0,10=>10,20=>20,30=>30,40=>40,50=>50,60=>60,70=>70,80=>80,90=>90,100=>100);
+	$form->addElement ('select', 'progress',get_lang('Progress'),$options_select);
+	$default['progress'] = intval($progress);	
+}
+
+$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
+// Set some default values
+$default['title'] = Security::remove_XSS($description_title);
+$default['contentDescription'] = Security::remove_XSS($description_content,STUDENT);
+$default['description_type'] = $description_type;
+
+$form->setDefaults($default);
+
+//***********************************			
+if (isset ($question[$description_type])) {
+	$message = '<strong>'.get_lang('QuestionPlan').'</strong><br />';
+	$message .= $question[$description_type];
+	Display::display_normal_message($message, false);
+}
+
+
+if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+	echo (WCAG_Rendering::editor_header());
+}
+
+$form->display();
+if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
+	echo (WCAG_Rendering::editor_footer());
+}
+
+?>

+ 64 - 343
main/course_description/index.php

@@ -1,47 +1,48 @@
-<?php // $Id: index.php 22253 2009-07-20 17:03:48Z ivantcholakov $
+<?php
 /* For licensing terms, see /dokeos_license.txt */
+
 /**
-==============================================================================
-*	This script edits the course description.
-*	This script is reserved for users with write access on the course.
-*
-*	@author Thomas Depraetere
-*	@author Hugues Peeters
-*	@author Christophe Gesché
-*	@author Olivier brouckaert
-*	@package dokeos.course_description
-==============================================================================
+* Template (front controller in MVC pattern) used for distpaching to the controllers depend on the current action  
+* @package dokeos.course_description
+* @author Christian Fasanando <christian1827@gmail.com>
 */
 
-/*
-==============================================================================
-		INIT SECTION
-==============================================================================
-*/
 // name of the language file that needs to be included
 $language_file = array ('course_description', 'pedaSuggest', 'accessibility');
 
-include '../inc/global.inc.php';
-$this_section = SECTION_COURSES;
-$session_id = api_get_session_id();
+// including files 
+require_once '../inc/global.inc.php';
 
-include api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
+require_once api_get_path(LIBRARY_PATH).'course_description.lib.php';
+require_once api_get_path(LIBRARY_PATH).'app_view.php';
+require_once api_get_path(LIBRARY_PATH).'app_controller.php';
+require_once 'course_description_controller.php';
+require_once api_get_path(LIBRARY_PATH).'formvalidator/FormValidator.class.php';
+require_once api_get_path(LIBRARY_PATH).'WCAG/WCAG_rendering.php';
 
-include_once api_get_path(LIBRARY_PATH).'WCAG/WCAG_rendering.php';
-/*
------------------------------------------------------------
-	Header
------------------------------------------------------------
-*/
+// defining constants
+define('ADD_BLOCK', 9);
+define('THEMATIC_ADVANCE', 8);
 
-$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('CourseProgram'));
+// current section
+$this_section = SECTION_COURSES;
+
+api_protect_course_script(true);
+
+// get actions
+$actions = array('listing', 'add', 'edit', 'delete', 'history');
+$action = 'listing';
+if (isset($_GET['action']) && in_array($_GET['action'],$actions)) {
+	$action = $_GET['action'];
+}
 
-$description_type = isset ($_REQUEST['description_type']) ? Security::remove_XSS($_REQUEST['description_type']) : null;
-$description_id = isset ($_REQUEST['description_id']) ? Security::remove_XSS($_REQUEST['description_id']) : null;
-$action = isset($_GET['action'])?Security::remove_XSS($_GET['action']):'';
-$edit = isset($_POST['edit'])?Security::remove_XSS($_POST['edit']):'';
-$add = isset($_POST['add'])?Security::remove_XSS($_POST['add']):'';
+$description_type = '';
+if (isset($_GET['description_type'])) {
+	$description_type = intval($_GET['description_type']);
+}
 
+// interbreadcrumb
+$interbreadcrumb[] = array ("url" => "index.php", "name" => get_lang('CourseProgram'));
 if(intval($description_type) == 1) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('GeneralDescription'));
 if(intval($description_type) == 2) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('Objectives'));
 if(intval($description_type) == 3) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('Topics'));
@@ -49,316 +50,36 @@ if(intval($description_type) == 4) $interbreadcrumb[] = array ("url" => "#", "na
 if(intval($description_type) == 5) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('CourseMaterial'));
 if(intval($description_type) == 6) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('HumanAndTechnicalResources'));
 if(intval($description_type) == 7) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('Assessment'));
-if(intval($description_type) >= 8) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('NewBloc'));
-
-api_protect_course_script(true);
-$nameTools = get_lang('CourseProgram');
-Display :: display_header('');
-//api_display_tool_title($nameTools);
-
-
-
-/*
------------------------------------------------------------
-	Constants and variables
------------------------------------------------------------
-*/
-$nameTools = get_lang(TOOL_COURSE_DESCRIPTION);
-
-
-/*
------------------------------------------------------------
-	Introduction section
------------------------------------------------------------
-*/
-Display::display_introduction_section(TOOL_COURSE_DESCRIPTION);
-
-
-$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
-$show_description_list = true;
-$show_peda_suggest = true;
-define('ADD_BLOCK', 8);
-// Default descriptions
-$default_description_titles = array();
-$default_description_titles[1]= get_lang('GeneralDescription');
-$default_description_titles[2]= get_lang('Objectives');
-$default_description_titles[3]= get_lang('Topics');
-$default_description_titles[4]= get_lang('Methodology');
-$default_description_titles[5]= get_lang('CourseMaterial');
-$default_description_titles[6]= get_lang('HumanAndTechnicalResources');
-$default_description_titles[7]= get_lang('Assessment');
-$default_description_titles[8]= get_lang('Other');
-$default_description_icon = array();
-$default_description_icon[1]= 'edu_miscellaneous.gif';
-$default_description_icon[2]= 'spire.gif';
-$default_description_icon[3]= 'kcmdf_big.gif';
-$default_description_icon[4]= 'misc.gif';
-$default_description_icon[5]= 'laptop.gif';
-$default_description_icon[6]= 'personal.gif';
-$default_description_icon[7]= 'korganizer.gif';
-$default_description_icon[8]= 'ktip.gif';
-$question = array();
-$question[1]= get_lang('GeneralDescriptionQuestions');
-$question[2]= get_lang('ObjectivesQuestions');
-$question[3]= get_lang('TopicsQuestions');
-$question[4]= get_lang('MethodologyQuestions');
-$question[5]= get_lang('CourseMaterialQuestions');
-$question[6]= get_lang('HumanAndTechnicalResourcesQuestions');
-$question[7]= get_lang('AssessmentQuestions');
-$information = array();
-$information[1]= get_lang('GeneralDescriptionInformation');
-$information[2]= get_lang('ObjectivesInformation');
-$information[3]= get_lang('TopicsInformation');
-$information[4]= get_lang('MethodologyInformation');
-$information[5]= get_lang('CourseMaterialInformation');
-$information[6]= get_lang('HumanAndTechnicalResourcesInformation');
-$information[7]= get_lang('AssessmentInformation');
-$default_description_title_editable = array();
-$default_description_title_editable[1] = true;
-$default_description_title_editable[2] = true;
-$default_description_title_editable[3] = true;
-$default_description_title_editable[4] = true;
-$default_description_title_editable[5] = true;
-$default_description_title_editable[6] = true;
-$default_description_title_editable[7] = true;
-
-/*
------------------------------------------------------------
-	Tracking
------------------------------------------------------------
-*/
-event_access_tool(TOOL_COURSE_DESCRIPTION);
-
-/*
-==============================================================================
-		MAIN CODE
-==============================================================================
-*/
-
-$condition_session = api_get_session_condition($session_id, false);
-$current_session_id = api_get_session_id();
-
-
-$sql = "SELECT description_type,title FROM $tbl_course_description $condition_session ORDER BY description_type ";
-
-$result = Database::query($sql, __FILE__, __LINE__);
-while ($row = Database::fetch_array($result)) {
-  $default_description_titles[$row['description_type']] = $row['title'];
-}
-
-$actions = array('add','delete','edit');
-
-if ((api_is_allowed_to_edit(null,true) && !is_null($description_type)) || in_array($action,$actions)) {
-	
-	$description_id = intval($description_id);
-	$description_type = intval($description_type);
-
-	// Delete a description block
-	if ($action == 'delete') {	
-		$sql = "DELETE FROM $tbl_course_description WHERE id='".$description_id."'";
-		Database::query($sql, __FILE__, __LINE__);
-		//update item_property (delete)
-		api_item_property_update(api_get_course_info(), TOOL_COURSE_DESCRIPTION, Database::escape_string($description_id), 'delete', api_get_user_id());
-		Display :: display_confirmation_message(get_lang('CourseDescriptionDeleted'));
-	}
-	// Add or edit a description block
-	else {
-
-		if (!empty($description_type)) {			
-			$sql = "SELECT * FROM $tbl_course_description WHERE description_type='$description_type' AND session_id='$current_session_id'";		
-			$result = Database::query($sql, __FILE__, __LINE__);					
-			if ($description = Database::fetch_array($result)) {
-				$default_description_titles[$description_type] = $description['title'];
-				$description_content = $description['content'];
-
-			} else {
-				$current_title = $default_description_titles[$description_type];
-			}
-
-		} else {
-			$sql = "SELECT MAX(description_type) as MAX FROM $tbl_course_description $condition_session";			
-			$result = Database::query($sql, __FILE__, __LINE__);
-			$max= Database::fetch_array($result);
-			$description_type = $max['MAX']+1;
-			if ($description_type < ADD_BLOCK) {
-					$description_type=8;
-			}			
-		}
-		//Se borro: echo ' <style> .row{} <\style> por que hacia conflicto en apartado personalizado con los estilos propios del formvalidator
-		// Build the form
-		$form = new FormValidator('course_description','POST','index.php?'.api_get_cidreq(),'','style="width: 100%;"');
-		$form->addElement('header', '', $default_description_titles[$description_type]);
-		$form->addElement('hidden', 'description_type');
-
-		if ($action == 'edit' || intval($edit) == 1 ) {
-			$form->addElement('hidden', 'edit','1');
-		}
-
-		if ($action == 'add' || intval($add) == 1 ) {
-			$form->addElement('hidden', 'add','1');
-		}
-
-		if (($description_type >= ADD_BLOCK) || $default_description_title_editable[$description_type] || $action == 'add' || intval($edit) == 1) {
-			$form->add_textfield('title', get_lang('Title'), true, array('size'=>'width: 350px;'));
-			$form->applyFilter('title','html_filter');
-		}
-
-		if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
-			WCAG_rendering::prepare_admin_form($description_content, $form);
-		} else {
-			$form->add_html_editor('contentDescription', get_lang('Content'), true, false, array('ToolbarSet' => 'TrainingDescription', 'Width' => '100%', 'Height' => '200'));
-		}
-		$form->addElement('style_submit_button', null, get_lang('Save'), 'class="save"');
-		// Set some default values
-		$default['title'] = $default_description_titles[$description_type];
-		$default['contentDescription'] = $description_content;
-		$default['description_id'] = $description_id;
-		$default['description_type'] = $description_type;
-		//if ($description_id >= ADD_BLOCK) {
-			//$default['description_id'] = ADD_BLOCK;
-		//}
-		$form->setDefaults($default);
-		// If form validates: save the description block
-		if ($form->validate()) {
-			$description = $form->exportValues();
-			if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
-				$content = WCAG_Rendering::prepareXHTML();
-			} else {
-				$content = $description['contentDescription'];
-			}
-			$title = $description['title'];
-			if ($description['description_type'] >= ADD_BLOCK) {
-				if ($description['add']=='1') { //if this element has been submitted for addition
-					$result = Database::query($sql, __FILE__, __LINE__);
-					$sql = "INSERT IGNORE INTO $tbl_course_description SET description_type='$description_type', title = '".Database::escape_string(Security::remove_XSS($title,COURSEMANAGERLOWSECURITY))."', content = '".Database::escape_string(Security::remove_XSS($content,COURSEMANAGERLOWSECURITY))."', session_id = '$current_session_id' ";
-					Database::query($sql, __FILE__, __LINE__);
-				} else {
-					$sql = "UPDATE $tbl_course_description SET  title = '".Database::escape_string(Security::remove_XSS($title,COURSEMANAGERLOWSECURITY))."', content = '".Database::escape_string(Security::remove_XSS($content,COURSEMANAGERLOWSECURITY))."' WHERE description_type='$description_type' AND session_id = '$current_session_id'";
-					Database::query($sql, __FILE__, __LINE__);
-				}
-			} else {
-				//if title is not editable, then use default title
-				if (!$default_description_title_editable[$description_type]) {
-					$title = $default_description_titles[$description_type];
-				}
-				$sql = "DELETE FROM $tbl_course_description WHERE description_type = '".$description_type."' AND session_id = '$current_session_id'";
-				Database::query($sql, __FILE__, __LINE__);
-				$sql = "INSERT INTO $tbl_course_description SET description_type = '".$description_type."', title = '".Database::escape_string(Security::remove_XSS($title,COURSEMANAGERLOWSECURITY))."', content = '".Database::escape_string(Security::remove_XSS($content,COURSEMANAGERLOWSECURITY))."', session_id = '$current_session_id' ";
-				Database::query($sql, __FILE__, __LINE__);
-			}
-			$id = Database::insert_id();
-			if ($id > 0) {
-				//insert into item_property
-				api_item_property_update(api_get_course_info(), TOOL_COURSE_DESCRIPTION, $id, 'CourseDescriptionAdded', api_get_user_id());
-			}
-			Display :: display_confirmation_message(get_lang('CourseDescriptionUpdated'));
-		}
-		// Show the form
-		else {
-			// menu top
-			//***********************************
-			if (api_is_allowed_to_edit(null,true)) {
-				$categories = array ();
-
-				foreach ($default_description_titles as $id => $title) {
-					$categories[$id] = $title;
-				}
-				$categories[ADD_BLOCK] = get_lang('NewBloc');
-
-				$i=1;
-				echo '<div class="actions">';
-				ksort($categories);
-				foreach ($categories as $id => $title) {
-					if ($i==8) {
-						echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=add">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>';
+if(intval($description_type) == 8) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('ThematicAdvance'));
+if(intval($description_type) >= 9) $interbreadcrumb[] = array ("url" => "#", "name" => get_lang('Others'));
+
+// course description controller object
+$course_description_controller = new CourseDescriptionController();
+
+// distpacher actions to controller
+switch ($action) {	
+	case 'listing':	
+						$course_description_controller->listing();
+						break;	
+	case 'history':		
+						$course_description_controller->listing(true);
 						break;
-					} else {
-						echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&description_type='.$id.'">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>&nbsp;&nbsp;';
-						$i++;
-					}
-				}
-				echo '</div>';
-			}
-				//***********************************
-			if ($show_peda_suggest) {
-				if (isset ($question[$description_id])) {
-					$message = '<strong>'.get_lang('QuestionPlan').'</strong><br />';
-					$message .= $question[$description_id];
-					Display::display_normal_message($message, false);
-				}
-			}
-			if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
-				echo (WCAG_Rendering::editor_header());
-			}
-			$form->display();
-			if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
-				echo (WCAG_Rendering::editor_footer());
-			}
-			$show_description_list = false;
-		}
-	}
-}
-
-// Show the list of all description blocks
-if ($show_description_list) {
-	$sql = "SELECT * FROM $tbl_course_description $condition_session ORDER BY id ";
-	$result = Database::query($sql, __FILE__, __LINE__);
-	$descriptions = array();
-	while ($description = Database::fetch_object($result)) {
-		$descriptions[$description->description_type] = $description;
-		//reload titles to ensure we have the last version (after edition)
-		$default_description_titles[$description->description_type] = $description->title;
-	}
-	if (api_is_allowed_to_edit(null,true)) {
-		$categories = array ();
-
-		foreach ($default_description_titles as $id => $title) {
-			$categories[$id] = $title;
-		}
-		$categories[ADD_BLOCK] = get_lang('NewBloc');
-
-		$i=1;
-		echo '<div class="actions" style="margin-bottom:30px">';
-		ksort($categories);
-		foreach ($categories as $id => $title) {
-			if ($i==8) {
-				echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=add">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>';
-				break;
-			} else {
-				echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&description_type='.$id.'">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>&nbsp;&nbsp;';
-				$i++;
-			}
-		}
-		echo '</div>';
-	}
-	if (isset($descriptions) && count($descriptions) > 0) {
-		foreach ($descriptions as $id => $description) {
-			echo '<div class="sectiontitle">';
-			if (api_is_allowed_to_edit(null,true)) {
-				//delete
-				echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;action=delete&amp;description_id='.$description->id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)).'\')) return false;">';
-				echo Display::return_icon('delete.gif', get_lang('Delete'), array('style' => 'vertical-align:middle;float:right;'));
-				echo '</a> ';
-
-				//edit
-				echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;action=edit&amp;description_id='.$description->id.'&amp;description_type='.$description->description_type.'">';
-				echo Display::return_icon('edit.gif', get_lang('Edit'), array('style' => 'vertical-align:middle;float:right; padding-right:4px;'));
-				echo '</a> ';
-			}
-			echo $description->title;
-			echo '</div>';
-			echo '<div class="sectioncomment">';
-			echo text_filter($description->content);
-			echo '</div>';
-		}
-	} else {
-		echo '<em>'.get_lang('ThisCourseDescriptionIsEmpty').'</em>';
-	}
+	case 'add'	  :   
+						if (api_is_allowed_to_edit(null,true)) {
+							$course_description_controller->add();
+						}
+						break;
+	case 'edit'	  :	
+						if (api_is_allowed_to_edit(null,true)) {
+							$course_description_controller->edit($description_type);
+						}
+						break;
+	case 'delete' :	
+						if (api_is_allowed_to_edit(null,true)) {
+							$course_description_controller->destroy($description_type);
+						}
+						break;
+	default		  :	
+						$course_description_controller->listing();
 }
-/*
-==============================================================================
-		FOOTER
-==============================================================================
-*/
-Display :: display_footer();
-?>
+?>

+ 29 - 0
main/course_description/layout.php

@@ -0,0 +1,29 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+* Layout (principal view) used for structuring other views  
+* @package dokeos.course_description
+* @author Christian Fasanando <christian1827@gmail.com>
+*/
+
+// Header
+api_protect_course_script(true);
+$nameTools = get_lang('CourseProgram');
+Display :: display_header('');
+
+// Constants and variables
+$nameTools = get_lang(TOOL_COURSE_DESCRIPTION);
+
+// Introduction section
+Display::display_introduction_section(TOOL_COURSE_DESCRIPTION);
+
+// Tracking
+event_access_tool(TOOL_COURSE_DESCRIPTION);
+
+// Display
+echo $content;
+
+// Footer
+Display :: display_footer();
+?>

+ 90 - 0
main/course_description/listing.php

@@ -0,0 +1,90 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+* Template (view in MVC pattern) used for listing course descriptions  
+* @package dokeos.course_description
+* @author Christian Fasanando <christian1827@gmail.com>
+*/
+
+api_protect_course_script(true);
+
+// display messages
+if ($messages['edit'] || $messages['add']) {
+	Display :: display_confirmation_message(get_lang('CourseDescriptionUpdated'));
+} else if ($messages['destroy']) {
+	Display :: display_confirmation_message(get_lang('CourseDescriptionDeleted'));
+}
+
+// display actions menu
+if (api_is_allowed_to_edit(null,true)) {
+	$categories = array ();
+	foreach ($default_description_titles as $id => $title) {
+		$categories[$id] = $title;
+	}
+	$categories[ADD_BLOCK] = get_lang('NewBloc');
+
+	$i=1;
+	echo '<div class="actions" style="margin-bottom:30px">';
+	ksort($categories);
+	foreach ($categories as $id => $title) {
+		if ($i==ADD_BLOCK) {
+			echo '<a href="index?'.api_get_cidreq().'&action=add">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>';
+			break;
+		} else {
+			echo '<a href="index.php?action=edit&'.api_get_cidreq().'&description_type='.$id.'">'.Display::return_icon($default_description_icon[$id], $title, array('height'=>'22')).' '.$title.'</a>&nbsp;&nbsp;';
+			$i++;
+		}
+	}
+	echo '</div>';
+}
+
+// display course description list
+
+if ($history) {
+	echo '<div><table width="100%"><tr><td><h3>'.get_lang('ThematicAdvanceHistory').'</h3></td><td align="right"><a href="index.php?action=listing">'.Display::return_icon('info.gif',get_lang('BackToCourseDesriptionList'),array('style'=>'vertical-align:middle;')).' '.get_lang('BackToCourseDesriptionList').'</a></td></tr></table></div>';
+}
+if (isset($descriptions) && count($descriptions) > 0) {
+	foreach ($descriptions as $id => $description) {
+		echo '<div class="sectiontitle">';
+		
+		if (api_is_allowed_to_edit(null,true) && !$history) {
+			
+			//delete
+			echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete&description_type='.$description['description_type'].'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)).'\')) return false;">';
+			echo Display::return_icon('delete.gif', get_lang('Delete'), array('style' => 'vertical-align:middle;float:right;'));
+			echo '</a> ';
+			
+			//edit
+			echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=edit&&description_type='.$description['description_type'].'">';
+			echo Display::return_icon('edit.gif', get_lang('Edit'), array('style' => 'vertical-align:middle;float:right; padding-right:4px;'));
+			echo '</a> ';
+			
+			if ($description['description_type'] == THEMATIC_ADVANCE) {
+				// thematic advance history link				
+				echo '<a href="index?action=history&description_type='.$description['description_type'].'">';
+				echo Display::return_icon('lp_dir.png',get_lang('ThematicAdvanceHistory'),array('style'=>'vertical-align:middle;float:right;padding-right:4px;'));
+				echo '</a> ';					
+			}
+		}
+		
+		if ($description['description_type'] == THEMATIC_ADVANCE) {
+			$progress_icon = (isset($description['progress_icon'])?$description['progress_icon']:'');
+			echo get_lang('ThematicAdvance').' : '.$description['title'].' - '.$progress_icon;
+		} else {
+			echo $description['title'];
+		}	
+		
+		if ($history) {
+			echo ' ('.$description['lastedit_date'].') ';
+		}
+
+		echo '</div>';
+		echo '<div class="sectioncomment">';
+		echo text_filter($description['content']);
+		echo '</div>';
+	}
+} else {
+	echo '<em>'.get_lang('ThisCourseDescriptionIsEmpty').'</em>';
+}
+?>

+ 6 - 3
main/inc/lib/add_course.lib.inc.php

@@ -122,7 +122,7 @@ function define_course_keys($wantedCode, $prefix4all = "", $prefix4baseName = ""
 		$keysAreUnique = true;
 
 		// check if they are unique
-		$query = "SELECT 1 FROM ".$course_table . " WHERE code='".$keysCourseId . "' LIMIT 0,1";
+		echo $query = "SELECT 1 FROM ".$course_table . " WHERE code='".$keysCourseId . "' LIMIT 0,1";
 		$result = Database::query($query, __FILE__, __LINE__);
 
 		if($keysCourseId == DEFAULT_COURSE || Database::num_rows($result))
@@ -716,7 +716,8 @@ function update_Db_course($courseDbName, $language = null)
 		title VARCHAR(255),
 		content TEXT,
 		session_id smallint default 0,
-		description_type tinyint unsigned NOT NULL default 0,		
+		description_type tinyint unsigned NOT NULL default 0,
+		progress INT NOT NULL default 0,
 		UNIQUE (id)
 		)" . $charset_clause;
 	Database::query($sql, __FILE__, __LINE__);
@@ -1075,6 +1076,7 @@ function update_Db_course($courseDbName, $language = null)
 		)" . $charset_clause, __FILE__, __LINE__);
 
 	Database::query("CREATE TABLE `".$TABLEITEMPROPERTY . "` (
+		id int NOT NULL auto_increment,
 		tool varchar(100) NOT NULL default '',
 		insert_user_id int unsigned NOT NULL default '0',
 		insert_date datetime NOT NULL default '0000-00-00 00:00:00',
@@ -1087,7 +1089,8 @@ function update_Db_course($courseDbName, $language = null)
 		visibility tinyint NOT NULL default '1',
 		start_visible datetime NOT NULL default '0000-00-00 00:00:00',
 		end_visible datetime NOT NULL default '0000-00-00 00:00:00',
-		id_session INT NOT NULL DEFAULT 0
+		id_session INT NOT NULL DEFAULT 0,
+		PRIMARY KEY (id)
 		)" . $charset_clause, __FILE__, __LINE__);
 	Database::query("ALTER TABLE `$TABLEITEMPROPERTY` ADD INDEX idx_item_property_toolref (tool,ref)", __FILE__, __LINE__);
 

+ 89 - 0
main/inc/lib/app_view.php

@@ -0,0 +1,89 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+ * This library provides methods for using views with MVC pattern
+ * @package dokeos.library
+ * @author Christian Fasanando <christian1827@gmail.com>
+ */
+
+class ViewException extends Exception {}
+class View {
+	
+	private $data;
+	private $template;
+	private $layout;
+    private $tool_path;
+   
+   	/**
+   	 * Constructor, init tool path for rendering
+   	 * @param string  tool name (optional)
+   	 */
+	public function __construct($toolname = '') {		
+		if (!empty($toolname)) {
+			$path = api_get_path(SYS_CODE_PATH).$toolname.'/';
+			if (is_dir($path)) {
+				$this->tool_path = $path;	
+			} else {
+				throw new ViewException('View::__construct() $path directory does not exist ' . $path);
+			}				
+		}		
+	}
+   
+    /**
+   	 * Set data sent from a controller 
+   	 * @param array data
+   	 */
+	public function set_data($data) {
+		if (!is_array($data)) {
+			throw new ViewException('View::set_data() $data must to be an array, you have sent a' . gettype( $data ));
+		}
+		$this->data = $data;
+	}
+   
+    /**
+   	 * Set layout view sent from a controller 
+   	 * @param string layout view
+   	 */
+	public function set_layout( $layout ) {		
+		$this->layout = $layout;
+	}
+   
+   	/**
+   	 * Set template view sent from a controller 
+   	 * @param string template view
+   	 */
+	public function set_template($template) {		
+		$this->template = $template;
+	}
+
+	/**
+   	 * Render data to the template and layout views  
+   	 */
+	public function render() {
+		$content = $this->render_template();
+		$target = $this->tool_path.$this->layout.'.php';
+		if (file_exists($target)) {           
+			require_once $target;
+		} else {
+			throw new ViewException('View::render() invalid file path '.$target);
+		}
+	}
+    
+    /**
+   	 * It's used into render method for rendering data the template and layout views   
+   	 */   
+	private function render_template() {		
+		$target = $this->tool_path.$this->template.'.php';
+		if (file_exists($target)) {           
+			ob_start();
+			@extract($this->data, EXTR_OVERWRITE);
+			require_once $target;
+			$content = ob_get_clean();
+			return $content;
+		} else {
+			throw new ViewException('View::render_template() invalid file path '.$target);
+		}
+	}
+}
+?>

+ 410 - 0
main/inc/lib/course_description.lib.php

@@ -0,0 +1,410 @@
+<?php
+/* For licensing terms, see /dokeos_license.txt */
+
+/**
+ * This library provides functions for course description tool. It's also used like model to course_description_controller (MVC pattern)
+ * @package dokeos.library
+ * @author Christian Fasanando <christian1827@gmail.com>
+ */
+
+class CourseDescription
+{	
+	private $id;
+	private $title;
+	private $content;
+    private $session_id;
+    private $description_type;
+    private $progress;
+   
+   	/**
+	 * Constructor
+	 */
+	public function __construct() {}
+   
+    /**
+     * Get all data of course description by session id, 
+     * first you must set session_id property with the object CourseDescription
+     * @return array 
+     */
+	public function get_description_data() {				
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
+		$sql = "SELECT * FROM $tbl_course_description WHERE session_id = '".$this->session_id."' ORDER BY id ";
+		$rs = Database::query($sql, __FILE__, __LINE__);		
+		$data = array();		
+		while ($description = Database::fetch_array($rs)) {
+			if ($description['description_type'] == THEMATIC_ADVANCE) {
+				$description['progress_icon'] = $this->get_progress_porcent();
+			}
+			$data['descriptions'][$description['description_type']] = $description;			
+			//reload titles to ensure we have the last version (after edition)
+			$data['default_description_titles'][$description['description_type']] = $description['title'];
+		}				
+		return $data;		
+	}
+	
+	/**
+     * Get all data of course description by session id, 
+     * first you must set session_id property with the object CourseDescription
+     * @return array 
+     */
+	public function get_description_history($description_type) {				
+		$tbl_stats_item_property = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY);
+		$tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
+		$course_id = api_get_real_course_id();
+
+		$description_id = $this->get_id_by_description_type($description_type);		
+		$item_property_id = api_get_item_property_id($course_id, TOOL_COURSE_DESCRIPTION, $description_id);
+							
+		$sql = "SELECT * FROM $tbl_stats_item_property tip
+				INNER JOIN $tbl_item_property ip ON ip.tool = '".TOOL_COURSE_DESCRIPTION."' AND ip.id = tip.item_property_id
+				WHERE tip.course_id = '$course_id' AND tip.session_id = '".intval($this->session_id)."'";
+
+		$rs = Database::query($sql, __FILE__, __LINE__);		
+		$data = array();		
+		while ($description = Database::fetch_array($rs)) {
+			$data['descriptions'][] = $description;
+		}				
+		return $data;		
+	}
+	
+	/**
+     * Get all data by description and session id, 
+     * first you must set session_id property with the object CourseDescription
+     * @param 	int	description type
+     * @return array
+     */
+	public function get_data_by_description_type($description_type) {		
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
+		$sql = "SELECT * FROM $tbl_course_description WHERE description_type='$description_type' AND session_id='".$this->session_id."'";
+		$rs = Database::query($sql, __FILE__, __LINE__);				
+		$data = array();		
+		if ($description = Database::fetch_array($rs)) {
+			$data['description_title']	 = $description['title'];
+			$data['description_content'] = $description['content'];
+			$data['progress'] 			 = $description['progress'];
+		}						
+		return $data;		
+	}
+	
+	/**
+     * Get maximum description type by session id, first you must set session_id properties with the object CourseDescription
+     * @return  int  maximum description time adding one
+     */
+	public function get_max_description_type() {
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
+		$sql = "SELECT MAX(description_type) as MAX FROM $tbl_course_description WHERE session_id='".$this->session_id."'";
+		$rs  = Database::query($sql, __FILE__, __LINE__);
+		$max = Database::fetch_array($rs);	
+		$description_type = $max['MAX']+1;
+		if ($description_type < ADD_BLOCK) {
+			$description_type = ADD_BLOCK;
+		}		
+		return $description_type;				
+	}
+	
+	/**
+     * Insert a description to the course_description table, 
+     * first you must set description_type, title, content, progress and session_id properties with the object CourseDescription
+     * @return  int  affected rows 
+     */
+	public function insert() {
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);		
+		$sql = "INSERT IGNORE INTO $tbl_course_description SET description_type='".intval($this->description_type)."', title = '".Database::escape_string($this->title)."', content = '".Database::escape_string($this->content)."', progress = '".intval($this->progress)."', session_id = '".intval($this->session_id)."' ";
+		Database::query($sql, __FILE__, __LINE__);
+		$last_id = Database::insert_id();
+		$affected_rows = Database::affected_rows();
+		if ($last_id > 0) {
+			//insert into item_property
+			api_item_property_update(api_get_course_info(), TOOL_COURSE_DESCRIPTION, $last_id, 'CourseDescriptionAdded', api_get_user_id());
+		}
+		return $affected_rows;
+							
+	}
+	
+	/**
+     * Insert a row like history inside track_e_item_property table  
+     * first you must set description_type, title, content properties with the object CourseDescription
+     * @param 	int 	description type
+     * @return  int		affected rows 
+     */
+	public function insert_stats($description_type) {		
+		$tbl_stats_item_property = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY);		
+		$description_id = $this->get_id_by_description_type($description_type);
+		$course_id = api_get_real_course_id();						
+		$course_code = api_get_course_id();
+		$item_property_id = api_get_item_property_id($course_code, TOOL_COURSE_DESCRIPTION, $description_id);		
+		$sql = "INSERT IGNORE INTO $tbl_stats_item_property SET
+				course_id = '$course_id',
+			 	item_property_id = '$item_property_id', 			 	
+			 	title = '".Database::escape_string($this->title)."', 
+			 	content = '".Database::escape_string($this->content)."',
+			 	lastedit_date = '".date('Y-m-d H:i:s')."',
+			 	lastedit_user_id = '".api_get_user_id()."',
+			 	session_id	= '".intval($this->session_id)."'";
+		Database::query($sql, __FILE__, __LINE__);	
+		$affected_rows = Database::affected_rows();
+		return $affected_rows;			
+	}
+	
+	/**
+     * Update a description, first you must set description_type, title, content, progress 
+     * and session_id properties with the object CourseDescription
+     * @return int	affected rows 
+     */
+	public function update() {		
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);		
+		$sql = "UPDATE $tbl_course_description SET  title = '".Database::escape_string($this->title)."', content = '".Database::escape_string($this->content)."', progress = '".$this->progress."' WHERE description_type='".intval($this->description_type)."' AND session_id = '".$this->session_id."'";		
+		Database::query($sql, __FILE__, __LINE__);
+		$affected_rows = Database::affected_rows();		
+		$description_id = $this->get_id_by_description_type($this->description_type);
+		if ($description_id > 0) {
+			//insert into item_property
+			api_item_property_update(api_get_course_info(), TOOL_COURSE_DESCRIPTION, $description_id, 'CourseDescriptionUpdated', api_get_user_id());
+		}
+		return $affected_rows;
+	}
+	
+	/**
+     * Delete a description, first you must set description_type and session_id properties with the object CourseDescription
+     * @return int	affected rows
+     */
+	public function delete() {		
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
+		$description_id = $this->get_id_by_description_type($this->description_type);		
+		$sql = "DELETE FROM $tbl_course_description WHERE description_type = '".intval($this->description_type)."' AND session_id = '".intval($this->session_id)."'";				
+		Database::query($sql, __FILE__, __LINE__);
+		$affected_rows = Database::affected_rows();		
+		if ($description_id > 0) {
+			//insert into item_property
+			api_item_property_update(api_get_course_info(), TOOL_COURSE_DESCRIPTION, $description_id, 'CourseDescriptionDeleted', api_get_user_id());
+		}
+		return $affected_rows;
+	}
+	
+	/**
+	 * Get description id by description type
+	 * @param int description type
+	 * @return int description id
+	 */
+	public function get_id_by_description_type($description_type) {		
+		$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
+		$sql = "SELECT id FROM $tbl_course_description WHERE description_type = '".intval($description_type)."'";
+		$rs  = Database::query($sql, __FILE__, __LINE__);
+		$row = Database::fetch_array($rs);
+		$description_id = $row['id']; 	
+		return $description_id;		
+	}
+	
+	/**
+	 * get thematic progress in porcent for a course, 
+	 * first you must set session_id property with the object CourseDescription
+	 * @param bool		true for showing a icon about the progress, false otherwise (optional)
+	 * @param int		Description type (optional)
+	 * @return string   img html
+	 */
+	 public function get_progress_porcent($with_icon = false, $description_type = THEMATIC_ADVANCE) {
+	 	$tbl_course_description = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
+	 	$session_id = intval($session_id);
+		$sql = "SELECT progress FROM $tbl_course_description WHERE description_type = '".intval($description_type)."' AND session_id = '".intval($this->session_id)."' ";
+		$rs  = Database::query($sql, __FILE__, __LINE__);
+		$progress = '';
+		$img = '';
+		$title = '0%';
+		$image = 'level_0.png';
+		if (Database::num_rows($rs) > 0) {
+			$row = Database::fetch_array($rs);		
+			$progress = $row['progress'].'%';
+			$image = 'level_'.$row['progress'].'.png';				
+		}		
+		if ($with_icon) {
+			$img = Display::return_icon($image,get_lang('ThematicAdvance'),array('style'=>'vertical-align:middle'));	
+		}					
+		$progress = $img.$progress;
+		return $progress;
+	 }
+	
+	/**
+	 * Get description titles by default
+	 * @return array 
+	 */
+	public function get_default_description_title() {		
+		$default_description_titles = array();
+		$default_description_titles[1]= get_lang('GeneralDescription');
+		$default_description_titles[2]= get_lang('Objectives');
+		$default_description_titles[3]= get_lang('Topics');
+		$default_description_titles[4]= get_lang('Methodology');
+		$default_description_titles[5]= get_lang('CourseMaterial');
+		$default_description_titles[6]= get_lang('HumanAndTechnicalResources');
+		$default_description_titles[7]= get_lang('Assessment');
+		$default_description_titles[8]= get_lang('ThematicAdvance');
+		$default_description_titles[9]= get_lang('Other');
+		return $default_description_titles;
+	}
+	
+	/**
+	 * Get description titles editable by default
+	 * @return array 
+	 */
+	public function get_default_description_title_editable() {
+		$default_description_title_editable = array();
+		$default_description_title_editable[1] = true;
+		$default_description_title_editable[2] = true;
+		$default_description_title_editable[3] = true;
+		$default_description_title_editable[4] = true;
+		$default_description_title_editable[5] = true;
+		$default_description_title_editable[6] = true;
+		$default_description_title_editable[7] = true;
+		$default_description_title_editable[8] = true;
+		return $default_description_title_editable;		
+	}
+	
+	/**
+	 * Get description icons by default
+	 * @return array 
+	 */
+	public function get_default_description_icon() {		
+		$default_description_icon = array();
+		$default_description_icon[1]= 'edu_miscellaneous.gif';
+		$default_description_icon[2]= 'spire.gif';
+		$default_description_icon[3]= 'kcmdf_big.gif';
+		$default_description_icon[4]= 'misc.gif';
+		$default_description_icon[5]= 'laptop.gif';
+		$default_description_icon[6]= 'personal.gif';
+		$default_description_icon[7]= 'korganizer.gif';
+		$default_description_icon[8]= 'porcent.png';
+		$default_description_icon[9]= 'ktip.gif';
+		return $default_description_icon;
+	}
+	
+	/**
+	 * Get questions by default for help 
+	 * @return array 
+	 */
+	public function get_default_question() {		
+		$question = array();
+		$question[1]= get_lang('GeneralDescriptionQuestions');
+		$question[2]= get_lang('ObjectivesQuestions');
+		$question[3]= get_lang('TopicsQuestions');
+		$question[4]= get_lang('MethodologyQuestions');
+		$question[5]= get_lang('CourseMaterialQuestions');
+		$question[6]= get_lang('HumanAndTechnicalResourcesQuestions');
+		$question[7]= get_lang('AssessmentQuestions');
+		$question[8]= get_lang('thematicAdvanceQuestions');
+		return $question;
+	}
+	
+	/**
+	 * Get informations by default for help 
+	 * @return array 
+	 */
+	public function get_default_information() {
+		$information = array();
+		$information[1]= get_lang('GeneralDescriptionInformation');
+		$information[2]= get_lang('ObjectivesInformation');
+		$information[3]= get_lang('TopicsInformation');
+		$information[4]= get_lang('MethodologyInformation');
+		$information[5]= get_lang('CourseMaterialInformation');
+		$information[6]= get_lang('HumanAndTechnicalResourcesInformation');
+		$information[7]= get_lang('AssessmentInformation');		
+		$information[8]= get_lang('ThematicAdvanceInformation');
+		return $information;
+	}
+	
+	/**
+	 * Set description id
+	 * @return void
+	 */
+	public function set_id($id) {
+		$this->id = $id;
+	}
+   
+   	/**
+	 * Set description title
+	 * @return void
+	 */
+	public function set_title($title) {
+		$this->title = $title;
+	}
+   
+    /**
+	 * Set description content
+	 * @return void
+	 */
+	public function set_content($content) {
+		$this->content = $content;
+	}
+	
+	/**
+	 * Set description session id
+	 * @return void
+	 */
+	public function set_session_id($session_id) {
+		$this->session_id = $session_id;
+	}
+   
+   	/**
+	 * Set description type
+	 * @return void
+	 */
+	public function set_description_type($description_type) {
+		$this->description_type = $description_type;
+	}
+	
+	/**
+	 * Set progress of a description
+	 * @return void
+	 */
+	public function set_progress($progress) {
+		$this->progress = $progress;
+	}
+	
+	/**
+	 * get description id
+	 * @return int
+	 */
+	public function get_id() {
+		return $this->id;
+	}
+	
+   	/**
+	 * get description title
+	 * @return string 
+	 */
+	public function get_title() {
+		return $this->title;
+	}
+   
+   	/**
+	 * get description content
+	 * @return string
+	 */
+	public function get_content() {
+		return $this->content;
+	}
+	
+	/**
+	 * get session id
+	 * @return int
+	 */
+	public function get_session_id() {
+		return $this->session_id;
+	}
+   
+   	/**
+	 * get description type
+	 * @return int
+	 */
+	public function get_description_type() {
+		return $this->description_type;
+	}
+	
+	/**
+	 * get progress of a description
+	 * @return int
+	 */
+	public function get_progress() {
+		return $this->progress;
+	}
+		
+}
+?>