Browse Source

Updating from 198.

Julio Montoya 10 years ago
parent
commit
6112c87468
56 changed files with 2826 additions and 1592 deletions
  1. 2 6
      main/admin/access_url_edit.php
  2. 1 6
      main/admin/access_urls.php
  3. 4 0
      main/admin/user_list.php
  4. 16 6
      main/calendar/agenda_js.php
  5. 18 11
      main/course_description/course_description_controller.php
  6. 8 3
      main/course_info/delete_course.php
  7. 13 0
      main/course_info/infocours.php
  8. 16 5
      main/dashboard/block.class.php
  9. 10 3
      main/dropbox/dropbox_download.php
  10. 34 15
      main/dropbox/dropbox_functions.inc.php
  11. 1 1
      main/forum/editpost.php
  12. 275 259
      main/forum/forumfunction.inc.php
  13. 0 3
      main/forum/forumqualify.php
  14. 67 34
      main/forum/index.php
  15. 3 3
      main/forum/newthread.php
  16. 3 2
      main/forum/reply.php
  17. 55 34
      main/forum/viewforum.php
  18. 1 1
      main/forum/viewforumcategory.php
  19. 5 3
      main/forum/viewpost.php
  20. 13 34
      main/forum/viewthread.php
  21. 24 9
      main/forum/viewthread_nested.inc.php
  22. 53 18
      main/forum/viewthread_threaded.inc.php
  23. 10 2
      main/gradebook/exercise_jump.php
  24. 10 2
      main/gradebook/gradebook_add_cat.php
  25. 25 10
      main/gradebook/gradebook_add_link.php
  26. 2 1
      main/gradebook/gradebook_add_result.php
  27. 4 1
      main/gradebook/gradebook_edit_cat.php
  28. 7 2
      main/gradebook/gradebook_edit_link.php
  29. 52 13
      main/gradebook/gradebook_flatview.php
  30. 4 15
      main/gradebook/gradebook_view_result.php
  31. 24 10
      main/gradebook/index.php
  32. 420 358
      main/gradebook/lib/be/abstractlink.class.php
  33. 159 75
      main/gradebook/lib/be/category.class.php
  34. 163 143
      main/gradebook/lib/be/evallink.class.php
  35. 100 54
      main/gradebook/lib/be/evaluation.class.php
  36. 39 17
      main/gradebook/lib/be/exerciselink.class.php
  37. 47 30
      main/gradebook/lib/be/linkfactory.class.php
  38. 38 31
      main/gradebook/lib/be/result.class.php
  39. 173 43
      main/gradebook/lib/fe/catform.class.php
  40. 44 16
      main/gradebook/lib/fe/displaygradebook.php
  41. 27 18
      main/gradebook/lib/fe/evalform.class.php
  42. 80 21
      main/gradebook/lib/fe/flatviewtable.class.php
  43. 96 35
      main/gradebook/lib/fe/gradebooktable.class.php
  44. 15 3
      main/gradebook/lib/fe/linkaddeditform.class.php
  45. 34 11
      main/gradebook/lib/fe/linkform.class.php
  46. 1 1
      main/gradebook/lib/fe/resulttable.class.php
  47. 279 75
      main/gradebook/lib/flatview_data_generator.class.php
  48. 44 18
      main/gradebook/lib/gradebook_data_generator.class.php
  49. 160 64
      main/gradebook/lib/gradebook_functions.inc.php
  50. 27 15
      main/gradebook/lib/results_data_generator.class.php
  51. 67 29
      main/gradebook/lib/scoredisplay.class.php
  52. 18 4
      main/group/group.php
  53. 0 1
      main/group/import.php
  54. 6 2
      main/inc/lib/api.lib.php
  55. 27 14
      main/inc/lib/certificate.lib.php
  56. 2 2
      main/newscorm/lp_list.php

+ 2 - 6
main/admin/access_url_edit.php

@@ -6,9 +6,7 @@
  * @author Julio Montoya <gugli100@gmail.com>
  * @author Yannick Warnier <yannick.warnier@beeznest.com>
  */
-/**
- * Initialization
- */
+
 $language_file = 'admin';
 $cidReset = true;
 require_once '../inc/global.inc.php';
@@ -149,9 +147,7 @@ if (!api_is_multiple_url_enabled()) {
 $tool_name = get_lang('AddUrl');
 $interbreadcrumb[] = array ("url" => 'index.php', "name" => get_lang('PlatformAdmin'));
 $interbreadcrumb[] = array ("url" => 'access_urls.php', "name" => get_lang('MultipleAccessURLs'));
-/**
- * View
- */
+
 Display :: display_header($tool_name);
 
 if (isset ($_GET['action'])) {

+ 1 - 6
main/admin/access_urls.php

@@ -6,9 +6,6 @@
  * @author Julio Montoya <gugli100@gmail.com>
  * @author Yannick Warnier <yannick.warnier@beeznest.com>
  */
-/**
- * Initialization
- */
 // name of the language file that needs to be included
 $language_file = 'admin';
 $cidReset = true;
@@ -30,9 +27,7 @@ Display :: display_header($tool_name);
 $my_user_url_list = api_get_access_url_from_user(api_get_user_id());
 $current_access_url_id = api_get_current_access_url_id();
 $url_list = UrlManager::get_url_data();
-/**
- * Controller
- */
+
 if (isset ($_GET['action'])) {
     if ($_GET['action'] == 'show_message') {
         Display :: display_normal_message(Security::remove_XSS(stripslashes($_GET['message'])));

+ 4 - 0
main/admin/user_list.php

@@ -527,6 +527,10 @@ function active_filter($active, $url_params, $row) {
  * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University, Belgium
  */
 function status_filter($status) {
+    if (empty($status)) {
+        return null;
+    }
+
 	$statusname = api_get_status_langvars();
 	return $statusname[$status];
 }

+ 16 - 6
main/calendar/agenda_js.php

@@ -6,6 +6,7 @@
 /**
  * INIT SECTION
  */
+use \ChamiloSession as Session;
 
 // name of the language file that needs to be included
 $language_file = array('agenda', 'group', 'announcements');
@@ -15,7 +16,8 @@ $use_anonymous = true;
 
 // Calendar type
 
-$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin')) ?  $_REQUEST['type'] : 'personal';
+$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin', 'platform')) ? $_REQUEST['type'] : 'personal';
+$userId = isset($_REQUEST['user_id']) ? $_REQUEST['user_id'] : null;
 
 if ($type == 'personal') {
     $cidReset = true; // fixes #5162
@@ -35,7 +37,7 @@ $htmlHeadXtra[] = api_get_js('fullcalendar/gcal.js');
 $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_JS_PATH).'fullcalendar/fullcalendar.css');
 $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_JS_PATH).'qtip2/jquery.qtip.min.css');
 
-if (api_is_platform_admin() && $type == 'admin') {
+if (api_is_platform_admin() && ($type == 'admin' || $type == 'platform')) {
     $type = 'admin';
 }
 
@@ -44,6 +46,8 @@ if (isset($_REQUEST['cidReq']) && !empty($_REQUEST['cidReq'])) {
     $type = 'course';
 }
 
+$agenda = new Agenda();
+$agenda->type = $type;
 $is_group_tutor = false;
 $session_id = api_get_session_id();
 $group_id = api_get_group_id();
@@ -51,8 +55,14 @@ $group_id = api_get_group_id();
 if (!empty($group_id)) {
     $is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
     $group_properties  = GroupManager :: get_group_properties($group_id);
-    $interbreadcrumb[] = array ("url" => "../group/group.php", "name" => get_lang('Groups'));
-    $interbreadcrumb[] = array ("url"=>"../group/group_space.php?gidReq=".$group_id, "name"=> get_lang('GroupSpace').' '.$group_properties['name']);
+    $interbreadcrumb[] = array(
+        "url" => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
+        "name" => get_lang('Groups')
+    );
+    $interbreadcrumb[] = array(
+        "url" => api_get_path(WEB_CODE_PATH)."group/group_space.php?".api_get_cidreq(),
+        "name" => get_lang('GroupSpace').' '.$group_properties['name']
+    );
 }
 
 $app['title'] = get_lang('Agenda');
@@ -70,7 +80,7 @@ switch($type) {
         }
         break;
     case 'course':
-        api_protect_course_script();
+        api_protect_course_script(true);
         $this_section = SECTION_COURSES;
         if (api_is_allowed_to_edit()) {
             $can_add_events = 1;
@@ -82,7 +92,7 @@ switch($type) {
         }
         break;
     case 'personal':
-        if (api_is_anonymous()) {
+        if (api_is_anonymous(null, true)) {
             api_not_allowed(true);
         }
         $extra_field_data = UserManager::get_extra_user_data_by_field(api_get_user_id(), 'google_calendar_url');

+ 18 - 11
main/course_description/course_description_controller.php

@@ -2,17 +2,14 @@
 /* For licensing terms, see /license.txt */
 
 /**
+ * Class CourseDescriptionController
  * This file contains class used like controller, it should be included inside a dispatcher file (e.g: index.php)
  * @author Christian Fasanando <christian1827@gmail.com>
  * @package chamilo.course_description
  */
 
-/**
- * Controller script. Prepares the common background variables to give to the scripts corresponding to
- * the requested action
- * @package chamilo.course_description 
- */
-class CourseDescriptionController { // extends Controller {	
+class CourseDescriptionController
+{
 		
 	private $toolname;    
 	private $view; 
@@ -20,7 +17,8 @@ class CourseDescriptionController { // extends Controller {
 	/**
 	 * Constructor
 	 */
-	public function __construct() {		
+	public function __construct()
+    {
 		$this->toolname = 'course_description';	
 		$this->view = new View($this->toolname);			
 	}
@@ -31,7 +29,8 @@ class CourseDescriptionController { // extends Controller {
 	 * @param boolean   	true for listing history (optional)
 	 * @param array 	message for showing by action['edit','add','destroy'] (optional) 
 	 */
-	public function listing($history=false, $messages=array()) {
+    public function listing($history=false, $messages=array())
+    {
 		$course_description = new CourseDescription();
 		$session_id = api_get_session_id();
 		$course_description->set_session_id($session_id);        
@@ -44,6 +43,11 @@ class CourseDescriptionController { // extends Controller {
 		$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;
+        $browser = api_get_navigator();
+
+        if (strpos($data['descriptions'], '<iframe') !== false && $browser['name'] == 'Chrome') {
+            header("X-XSS-Protection: 0");
+        }
 		
 		// render to the view
 		$this->view->set_data($data);
@@ -57,7 +61,8 @@ class CourseDescriptionController { // extends Controller {
 	 * render to listing or edit view
 	 * @param int description type
 	 */
-	public function edit($id, $description_type) {
+    public function edit($id, $description_type)
+    {
 		$course_description = new CourseDescription();
 		$session_id = api_get_session_id();
 		$course_description->set_session_id($session_id);		
@@ -151,7 +156,8 @@ class CourseDescriptionController { // extends Controller {
 	 * It's used for adding a course description,
 	 * render to listing or add view
 	 */
-	public function add() {
+	public function add()
+    {
 		$course_description = new CourseDescription();
 		$session_id = api_get_session_id();
 		$course_description->set_session_id($session_id);
@@ -216,7 +222,8 @@ class CourseDescriptionController { // extends Controller {
 	 * render to listing view
 	 * @param int description type
 	 */
-	public function destroy($id) {		
+	public function destroy($id)
+    {
 		$course_description = new CourseDescription();
 		$session_id = api_get_session_id();
 		$course_description->set_session_id($session_id);		

+ 8 - 3
main/course_info/delete_course.php

@@ -10,6 +10,7 @@
 /**
  * Code
  */
+use \ChamiloSession as Session;
 
 // Language files that need to be included
 $language_file = array('admin', 'course_info');
@@ -20,6 +21,7 @@ $this_section = SECTION_COURSES;
 $current_course_tool  = TOOL_COURSE_MAINTENANCE;
 api_protect_course_script(true);
 
+$_course = api_get_course_info();
 $current_course_code = $_course['official_code'];
 $current_course_name = $_course['name'];
 
@@ -34,8 +36,8 @@ if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
 	$obj_cat->update_category_delete($_course['sysCode']);
 
 	// DELETE CONFIRMATION MESSAGE
-	unset($_course);
-	unset($_cid);
+    Session::erase('_cid');
+    Session::erase('_real_cid');
 	$noPHP_SELF = true;
 	$message = '<h2>'.get_lang('Course').' : '.$current_course_name.' ('.$current_course_code.') </h2>';
     $message .=get_lang('HasDel');
@@ -43,7 +45,10 @@ if (isset($_GET['delete']) && $_GET['delete'] == 'yes') {
 
 } else {
     $message = '<h3>'.get_lang('Course').' : '.$current_course_name.' ('.$current_course_code.') </h3>';
-    $message .= '<p>'.get_lang('ByDel').'</p><p><a class="btn btn-primary" href="maintenance.php">'.get_lang('No').'</a>&nbsp;<a class="btn" href="'.api_get_self().'?delete=yes">'.get_lang('Yes').'</a></p>';
+    $message .= '<p>'.get_lang('ByDel').'</p>';
+    $message .= '<p><a class="btn btn-primary" href="'.api_get_path(WEB_CODE_PATH).'course_info/maintenance.php?'.api_get_cidreq().'">'.
+        get_lang('No').'</a>&nbsp;<a class="btn" href="'.api_get_self().'?delete=yes&'.api_get_cidreq().'">'.
+        get_lang('Yes').'</a></p>';
 	$interbreadcrumb[] = array('url' => 'maintenance.php', 'name' => get_lang('Maintenance'));
 }
 Display :: display_header($tool_name, 'Settings');

+ 13 - 0
main/course_info/infocours.php

@@ -228,6 +228,19 @@ $form->addElement('style_submit_button', null, get_lang('SaveSettings'), 'class=
 $form->addElement('html', '</div></div>');
 
 // EMAIL NOTIFICATIONS
+if (api_get_setting('documents_default_visibility_defined_in_course') == 'true') {
+    $form->addElement('html', '<div> <h3>'.Display::return_icon('folder.png', Security::remove_XSS(get_lang('Documents')),'',ICON_SIZE_SMALL).' '.Security::remove_XSS(get_lang('Documents')).'</h3><div>');
+
+    $group = array(
+        $form->createElement('radio', 'documents_default_visibility', null, get_lang('Visible'), 'visible'),
+        $form->createElement('radio', 'documents_default_visibility', null, get_lang('Invisible'), 'invisible')
+    );
+    $form->addGroup($group, '', array(get_lang("DocumentsDefaultVisibility")), '');
+
+    $form->addElement('style_submit_button', null, get_lang('SaveSettings'), 'class="save"');
+
+    $form->addElement('html', '</div></div>');
+}
 $form->addElement('html', '<div> <h3>'.Display::return_icon('mail.png', Security::remove_XSS(get_lang('EmailNotifications')),'',ICON_SIZE_SMALL).' '.Security::remove_XSS(get_lang('EmailNotifications')).'</h3><div>');
 
 $group = array();

+ 16 - 5
main/dashboard/block.class.php

@@ -12,24 +12,35 @@
  * @package chamilo.dashboard 
  */
  
-class Block {
+class Block
+{
 
 	/**
 	 * Contructor
 	 */
-    public function __construct() {}
+    public function __construct()
+    {
+
+    }
     
     /**
      * Display small blocks, @todo it will be implemented for next version
      */
-    public function display_small() {}
+    public function display_small()
+    {
+
+    }
     
     /**
      * Display larges blocks, @todo it will be implemented for next version
      */
-    public function display_large() {}
+    public function display_large()
+    {
     
-    public function get_block_path(){              
+    }
+
+    public function get_block_path()
+    {
         $result = get_class($this);
         return $result;
     }

+ 10 - 3
main/dropbox/dropbox_download.php

@@ -28,7 +28,11 @@ require_once api_get_path(LIBRARY_PATH).'document.lib.php';
 $course_id = api_get_course_int_id();
 $user_id = api_get_user_id();
 
-if (isset($_GET['cat_id']) AND is_numeric($_GET['cat_id']) AND $_GET['action'] == 'downloadcategory' AND isset($_GET['sent_received'])) {
+if (isset($_GET['cat_id']) AND
+    is_numeric($_GET['cat_id']) AND
+    $_GET['action'] == 'downloadcategory' AND
+    isset($_GET['sent_received'])
+) {
     /** step 1: constructing the sql statement.
     Due to the nature off the classes of the dropbox the categories for sent files are stored in the table
     dropbox_file while the categories for the received files are stored in dropbox_post.
@@ -39,7 +43,8 @@ if (isset($_GET['cat_id']) AND is_numeric($_GET['cat_id']) AND $_GET['action'] =
     if ($_GET['sent_received'] == 'sent') {
         // here we also incorporate the person table to make sure that deleted sent documents are not included.
         $sql = "SELECT DISTINCT file.id, file.filename, file.title
-                FROM ".$dropbox_cnf['tbl_file']." file INNER JOIN ".$dropbox_cnf['tbl_person']." person
+                FROM ".$dropbox_cnf['tbl_file']." file
+                INNER JOIN ".$dropbox_cnf['tbl_person']." person
                 ON (person.file_id=file.id AND file.c_id = $course_id AND person.c_id = $course_id)
                 WHERE
                     file.uploader_id = $user_id AND
@@ -49,7 +54,8 @@ if (isset($_GET['cat_id']) AND is_numeric($_GET['cat_id']) AND $_GET['action'] =
 
     if ($_GET['sent_received'] == 'received') {
         $sql = "SELECT DISTINCT file.id, file.filename, file.title
-                FROM ".$dropbox_cnf['tbl_file']." file INNER JOIN ".$dropbox_cnf['tbl_person']." person
+                FROM ".$dropbox_cnf['tbl_file']." file
+                INNER JOIN ".$dropbox_cnf['tbl_person']." person
                 ON (person.file_id=file.id AND file.c_id = $course_id AND person.c_id = $course_id)
                 INNER JOIN ".$dropbox_cnf['tbl_post']." post
                 ON (post.file_id = file.id AND post.c_id = $course_id AND file.c_id = $course_id)
@@ -58,6 +64,7 @@ if (isset($_GET['cat_id']) AND is_numeric($_GET['cat_id']) AND $_GET['action'] =
                     post.dest_user_id = $user_id" ;
     }
 
+    $files_to_download = array();
     $result = Database::query($sql);
     while ($row = Database::fetch_array($result)) {
         $files_to_download[] = $row['id'];

+ 34 - 15
main/dropbox/dropbox_functions.inc.php

@@ -90,7 +90,7 @@ function handle_multiple_actions()
               $to_cat_id = str_replace('move_sent_', '', $_POST['action']);
         }
 
-        foreach ($checked_file_ids as $key => $value) {
+        foreach ($checked_file_ids as $value) {
             store_move($value, $to_cat_id, $part);
         }
         return get_lang('FilesMoved');
@@ -1033,7 +1033,7 @@ function store_feedback()
 
 /**
 * This function downloads all the files of the inputarray into one zip
-* @param $array an array containing all the ids of the files that have to be downloaded.
+* @param array $fileList containing all the ids of the files that have to be downloaded.
 * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
 * @todo consider removing the check if the user has received or sent this file (zip download of a folder already sufficiently checks for this).
 * @todo integrate some cleanup function that removes zip files that are older than 2 days
@@ -1042,34 +1042,52 @@ function store_feedback()
 * @author Julio Montoya  Addin c_id support
 * @version march 2006
 */
-function zip_download($array) {
+function zip_download($fileList)
+{
 	$_course = api_get_course_info();
     $dropbox_cnf = getDropboxConf();
 
     $course_id = api_get_course_int_id();
-	$array = array_map('intval', $array);
+    $fileList = array_map('intval', $fileList);
 
 	// note: we also have to add the check if the user has received or sent this file.
 	$sql = "SELECT DISTINCT file.filename, file.title, file.author, file.description
-			FROM ".$dropbox_cnf['tbl_file']." file INNER JOIN ".$dropbox_cnf['tbl_person']." person
+			FROM ".$dropbox_cnf['tbl_file']." file
+			INNER JOIN ".$dropbox_cnf['tbl_person']." person
             ON (person.file_id=file.id AND file.c_id = $course_id AND person.c_id = $course_id)
             INNER JOIN ".$dropbox_cnf['tbl_post']." post
             ON (post.file_id = file.id AND post.c_id = $course_id AND file.c_id = $course_id)
-			WHERE   file.id IN (".implode(', ',$array).") AND
+			WHERE
+			    file.id IN (".implode(', ', $fileList).") AND
                     file.id = person.file_id AND
-                    (person.user_id = '".api_get_user_id()."' OR post.dest_user_id = '".api_get_user_id()."' ) ";
+                (
+                    person.user_id = '".api_get_user_id()."' OR
+                    post.dest_user_id = '".api_get_user_id()."'
+                ) ";
 	$result = Database::query($sql);
 	$files = array();
 	while ($row = Database::fetch_array($result)) {
-		$files[$row['filename']] = array('filename' => $row['filename'],'title' => $row['title'], 'author' => $row['author'], 'description' => $row['description']);
+		$files[$row['filename']] = array(
+            'filename' => $row['filename'],
+            'title' => $row['title'],
+            'author' => $row['author'],
+            'description' => $row['description']
+        );
 	}
 
 	// Step 3: create the zip file and add all the files to it
 	$temp_zip_file = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
-	$zip_folder = new PclZip($temp_zip_file);
+    Session::write('dropbox_files_to_download', $files);
+	$zip = new PclZip($temp_zip_file);
 	foreach ($files as $value) {
-		$zip_folder->add(api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'], PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_CB_PRE_ADD, 'my_pre_add_callback');
+        $zip->add(
+            api_get_path(SYS_COURSE_PATH).$_course['path'].'/dropbox/'.$value['filename'],
+            PCLZIP_OPT_REMOVE_ALL_PATH,
+            PCLZIP_CB_PRE_ADD,
+            'my_pre_add_callback'
+        );
 	}
+    Session::erase('dropbox_files_to_download');
 	$name = 'dropbox-'.api_get_utc_datetime().'.zip';
 	DocumentManager::file_send_for_download($temp_zip_file, true, $name);
 	@unlink($temp_zip_file);
@@ -1078,14 +1096,15 @@ function zip_download($array) {
 
 /**
 * This is a callback function to decrypt the files in the zip file to their normal filename (as stored in the database)
-* @param $p_event a variable of PCLZip
-* @param $p_header a variable of PCLZip
+* @param array $p_event a variable of PCLZip
+* @param array $p_header a variable of PCLZip
 *
 * @author Patrick Cool <patrick.cool@UGent.be>, Ghent University
 * @version march 2006
 */
-function my_pre_add_callback($p_event, &$p_header) {
-	global $files;
+function my_pre_add_callback($p_event, &$p_header)
+{
+    $files = Session::read('dropbox_files_to_download');
 	$p_header['stored_filename'] = $files[$p_header['stored_filename']]['title'];
 	return 1;
 }
@@ -1175,7 +1194,7 @@ function get_total_number_feedback($file_id = '') {
 */
 function check_number_feedback($key, $array) {
 	if (is_array($array)) {
-		if (key_exists($key, $array)) {
+		if (array_key_exists($key, $array)) {
 			return $array[$key];
 		} else {
 			return 0;

+ 1 - 1
main/forum/editpost.php

@@ -181,7 +181,7 @@ echo "</tr>";
 echo '</table>';
 
 // The form for the reply
-$values = show_edit_post_form($current_post, $current_thread, $current_forum, isset($_SESSION['formelements']) ? $_SESSION['formelements'] : '');
+$values = show_edit_post_form($forum_setting, $current_post, $current_thread, $current_forum, isset($_SESSION['formelements']) ? $_SESSION['formelements'] : '');
 
 if (!empty($values) and isset($_POST['SubmitPost'])) {
     store_edit_post($values);

File diff suppressed because it is too large
+ 275 - 259
main/forum/forumfunction.inc.php


+ 0 - 3
main/forum/forumqualify.php

@@ -101,9 +101,6 @@ if ($origin=='learnpath') {
 }
 
 
-/*
-    Is the user allowed here?
-*/
 // if the user is not a course administrator and the forum is hidden
 // then the user is not allowed here.
 if (!api_is_allowed_to_edit(false,true) AND ($current_forum['visibility']==0 OR $current_thread['visibility']==0)) {

+ 67 - 34
main/forum/index.php

@@ -25,11 +25,15 @@
  * Code
  */
 // Name of the language file that needs to be included.
-$language_file = 'forum';
+use \ChamiloSession as Session;
+// Name of the language file that needs to be included.
+$language_file = array('forum', 'link');
+
 
 // Including the global initialization file.
 require_once '../inc/global.inc.php';
 $current_course_tool  = TOOL_FORUM;
+$htmlHeadXtra[] = '<script>
 
 $htmlHeadXtra[] = '<script>
     $(document).ready(function(){ $(\'.hide-me\').slideUp() });
@@ -112,8 +116,7 @@ if ($actions == 'notify' && isset($_GET['content']) && isset($_GET['id'])) {
 }
 
 get_whats_new();
-$whatsnew_post_info = array();
-$whatsnew_post_info = $_SESSION['whatsnew_post_info'];
+$whatsnew_post_info = Session::read('whatsnew_post_info');
 
 /* TRACKING */
 
@@ -126,12 +129,11 @@ event_access_tool(TOOL_FORUM);
 */
 
 // Step 1: We store all the forum categories in an array $forum_categories.
-$forum_categories_list = get_forum_categories();
+$forumCategories = get_forum_categories();
 
 // Step 2: We find all the forums (only the visible ones if it is a student).
-$forum_list	= array();
-$forum_list	= get_forums();
 
+$forum_list	= get_forums('', '', apiGetDisplayGroupsForumInGeneralTool());
 $user_id = api_get_user_id();
 
 /* RETRIEVING ALL GROUPS AND THOSE OF THE USER */
@@ -164,61 +166,82 @@ echo '<div class="actions">';
 //if is called from learning path
 if (!empty($_GET['lp_id']) || !empty($_POST['lp_id'])){
     echo "<a href=\"../newscorm/lp_controller.php?".api_get_cidreq()."&gradebook=&action=add_item&type=step&lp_id=".$lp_id."#resource_tab-5\">".Display::return_icon('back.png', get_lang("BackTo").' '.get_lang("LearningPaths"),'',ICON_SIZE_MEDIUM)."</a>";
+        Display::return_icon('back.png', get_lang("BackTo").' '.get_lang("LearningPaths"),'',ICON_SIZE_MEDIUM)."</a>";
 }
 if (!empty($forum_list)) {
     echo search_link();
 }
 
 if (api_is_allowed_to_edit(false, true)) {
-    echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=add&amp;content=forumcategory&amp;lp_id='.$lp_id.'"> '.Display::return_icon('new_folder.png', get_lang('AddForumCategory'),'',ICON_SIZE_MEDIUM).'</a>';
-    if (is_array($forum_categories_list) and !empty($forum_categories_list)) {
-        echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=add&amp;content=forum&amp;lp_id='.$lp_id.'"> '.Display::return_icon('new_forum.png', get_lang('AddForum'),'',ICON_SIZE_MEDIUM).'</a>';
+    echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=add&amp;content=forumcategory&amp;lp_id='.$lp_id.'"> '.
+        Display::return_icon('new_folder.png', get_lang('AddForumCategory'),'',ICON_SIZE_MEDIUM).'</a>';
+    if (is_array($forumCategories) and !empty($forumCategories)) {
+        echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=add&amp;content=forum&amp;lp_id='.$lp_id.'"> '.
+            Display::return_icon('new_forum.png', get_lang('AddForum'),'',ICON_SIZE_MEDIUM).'</a>';
     }
 }
 
 echo '</div>';
 
 /* Display Forum Categories and the Forums in it */
+$forumsInNoCategory = get_forums_in_category(0);
+if (!empty($forumsInNoCategory)) {
+    $forumCategories = array_merge($forumCategories, array(
+        array(
+            'cat_id' => 0,
+            'session_id' => 0,
+            'visibility' => 1,
+            'cat_comment' => null
+            )
+        )
+    );
+}
 
 // Step 3: We display the forum_categories first.
-if (is_array($forum_categories_list)) {
-    foreach ($forum_categories_list as $forum_category) {
 
+if (is_array($forumCategories)) {
+    foreach ($forumCategories as $forumCategory) {
          // The forums in this category.
-        $forums_in_category = get_forums_in_category($forum_category['cat_id']);
+        $forumsInCategory = get_forums_in_category($forumCategory['cat_id']);
 
-        echo '<table class="forum_table">';
+        $session_img = api_get_session_image($forumCategory['session_id'], $_user['status']);
 
         // Validacion when belongs to a session.
-        $session_img = api_get_session_image($forum_category['session_id'], $_user['status']);
-
-        if ((!isset($_SESSION['id_session']) || $_SESSION['id_session'] == 0) && !empty($forum_category['session_name'])) {
-            $session_displayed = ' ('.Security::remove_XSS($forum_category['session_name']).')';
+        if ((!isset($_SESSION['id_session']) || $_SESSION['id_session'] == 0) && !empty($forumCategory['session_name'])) {
+            $session_displayed = ' ('.Security::remove_XSS($forumCategory['session_name']).')';
         } else {
             $session_displayed = '';
         }
+        if (empty($forumCategory['cat_title'])) {
+            $forumCategory['cat_title'] = get_lang('WithoutCategory');
+        }
+
+        echo '<table class="forum_table">';
         echo '<thead>';
         echo '<tr><th class="forum_head" colspan="5">';
-        echo '<a href="viewforumcategory.php?'.api_get_cidreq().'&amp;forumcategory='.strval(intval($forum_category['cat_id'])).'" '.class_visible_invisible(strval(intval($forum_category['visibility']))).'>'.prepare4display($forum_category['cat_title']).$session_displayed.'</a>'. $session_img .'<br />';
-
-        if ($forum_category['cat_comment'] != '' && trim($forum_category['cat_comment']) != '&nbsp;') {
-            echo '<span class="forum_description">'.prepare4display($forum_category['cat_comment']).'</span>';
+        echo '<a href="viewforumcategory.php?'.api_get_cidreq().'&amp;forumcategory='.intval($forumCategory['cat_id']).'" '.class_visible_invisible($forumCategory['visibility']).'>'.
+            prepare4display($forumCategory['cat_title']).$session_displayed.
+            '</a>'. $session_img .'<br />';
+        if ($forumCategory['cat_comment'] != '' && trim($forumCategory['cat_comment']) != '&nbsp;') {
+            echo '<span class="forum_description">'.prepare4display($forumCategory['cat_comment']).'</span>';
         }
         echo '</th>';
 
         echo '<th style="vertical-align: top;" align="center" >';
-        if (api_is_allowed_to_edit(false, true) && !($forum_category['session_id'] == 0 && intval($session_id) != 0)) {
-            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=edit&amp;content=forumcategory&amp;id='.intval($forum_category['cat_id']).'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
-            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=delete&amp;content=forumcategory&amp;id='.intval($forum_category['cat_id'])."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeleteForumCategory'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a>';
-            display_visible_invisible_icon('forumcategory', strval(intval($forum_category['cat_id'])), strval(intval($forum_category['visibility'])));
-            display_lock_unlock_icon('forumcategory', strval(intval($forum_category['cat_id'])), strval(intval($forum_category['locked'])));
-            display_up_down_icon('forumcategory', strval(intval($forum_category['cat_id'])), $forum_categories_list);
+        if (!empty($forumCategory['cat_id'])) {
+            if (api_is_allowed_to_edit(false, true) && !($forumCategory['session_id'] == 0 && intval($session_id) != 0)) {
+                echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=edit&amp;content=forumcategory&amp;id='.intval($forumCategory['cat_id']).'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
+                echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=delete&amp;content=forumcategory&amp;id='.intval($forumCategory['cat_id'])."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeleteForumCategory'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a>';
+                display_visible_invisible_icon('forumcategory', strval(intval($forumCategory['cat_id'])), strval(intval($forumCategory['visibility'])));
+                display_lock_unlock_icon('forumcategory', strval(intval($forumCategory['cat_id'])), strval(intval($forumCategory['locked'])));
+                display_up_down_icon('forumcategory', strval(intval($forumCategory['cat_id'])), $forumCategories);
+            }
         }
         echo '</th>';
         echo '</tr>';
         echo '</thead>';
 
-        if (!empty($forums_in_category)) {
+        if (!empty($forumsInCategory)) {
 
             // Step 4: The interim headers (for the forum).
             echo '<tr class="forum_header">';
@@ -247,7 +270,7 @@ if (is_array($forum_categories_list)) {
                 }
 
                 // Note: This can be speeded up if we transform the $forum_list to an array that uses the forum_category as the key.
-                if ($forum['forum_category'] == $forum_category['cat_id']) {
+                if (isset($forum['forum_category']) && $forum['forum_category'] == $forumCategory['cat_id']) {
                     // The forum has to be showed if
                     // 1.v it is a not a group forum (teacher and student)
                     // 2.v it is a group forum and it is public (teacher and student)
@@ -279,7 +302,6 @@ if (is_array($forum_categories_list)) {
 
                         $forum_image = '';
 
-                        echo '<td width="20px">';
 
                         // Showing the image
                         if (!empty($forum['forum_image'])) {
@@ -292,13 +314,21 @@ if (is_array($forum_categories_list)) {
                                 if ($image_size['width'] > 100 || $image_size['height'] > 100) {
                                     //limit display width and height to 100px
                                     $img_attributes = ' style="width:100px" width="100px" height="100px"';
+									$td_width = 100;
+                                }
+								else
+								{
+									$td_width = $image_size['width'];
                                 }
                                 $forum_image =  "<img src=\"$image_path\" $img_attributes>";
                             } else {
                                 $forum_image = '';
+								$td_width = 20;
                             }
+							echo '<td width="'.$td_width.'px">';
                             echo $forum_image;
                         } else {
+							echo '<td width="20px">';
                             if ($forum['forum_of_group'] !== '0') {
                                 if (is_array($mywhatsnew_post_info) && !empty($mywhatsnew_post_info)) {
                                     echo Display::return_icon('forumgroupnew.gif');
@@ -369,11 +399,13 @@ if (is_array($forum_categories_list)) {
                         echo '</td>';
                         echo '<td class="td_actions">';
                         if (api_is_allowed_to_edit(false, true) && !($forum['session_id'] == 0 && intval($session_id) != 0)) {
-                            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=edit&amp;content=forum&amp;id='.$forum['forum_id'].'">'.Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
-                            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=delete&amp;content=forum&amp;id='.$forum['forum_id']."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeleteForum'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a>';
+                            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=edit&amp;content=forum&amp;id='.$forum['forum_id'].'">'.
+                                Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
+                            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=delete&amp;content=forum&amp;id='.$forum['forum_id']."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeleteForum'), ENT_QUOTES))."')) return false;\">".
+                                Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a>';
                             display_visible_invisible_icon('forum', $forum['forum_id'], $forum['visibility']);
                             display_lock_unlock_icon('forum', $forum['forum_id'], $forum['locked']);
-                            display_up_down_icon('forum', $forum['forum_id'], $forums_in_category);
+                            display_up_down_icon('forum', $forum['forum_id'], $forumsInCategory);
                         }
                         $iconnotify = 'send_mail.gif';
                         $session_forum_notification = isset($_SESSION['forum_notification']['forum']) ? $_SESSION['forum_notification']['forum'] : false;
@@ -384,7 +416,8 @@ if (is_array($forum_categories_list)) {
                         }
 
                         if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true) ) {
-                            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=notify&amp;content=forum&amp;id='.$forum['forum_id'].'">'.Display::return_icon($iconnotify, get_lang('NotifyMe')).'</a>';
+                            echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'&amp;action=notify&amp;content=forum&amp;id='.$forum['forum_id'].'">'.
+                                Display::return_icon($iconnotify, get_lang('NotifyMe')).'</a>';
                         }
                         echo '</td></tr>';
                     }

+ 3 - 3
main/forum/newthread.php

@@ -143,14 +143,14 @@ handle_forum_and_forumcategories();
 // Action links
 echo '<div class="actions">';
 echo '<span style="float:right;">'.search_link().'</span>';
-echo '<a href="viewforum.php?origin='.$origin.'&forum='.Security::remove_XSS($_GET['forum']).'&amp;gidReq='.Security::remove_XSS($_GET['gidReq']).'">'.Display::return_icon('back.png',get_lang('BackToForum'),'',ICON_SIZE_MEDIUM).'</a>';
+echo '<a href="viewforum.php?origin='.$origin.'&forum='.Security::remove_XSS($_GET['forum']).'&'.api_get_cidreq().'">'.Display::return_icon('back.png',get_lang('BackToForum'),'',ICON_SIZE_MEDIUM).'</a>';
 echo '</div>';
 
-$values = show_add_post_form('newthread', '', isset($_SESSION['formelements']) ? $_SESSION['formelements'] : null);
+$values = show_add_post_form($current_forum, $forum_setting, 'newthread', '', isset($_SESSION['formelements']) ? $_SESSION['formelements'] : null);
 
 if (!empty($values) && isset($values['SubmitPost'])) {
     // Add new thread in table forum_thread.
-    store_thread($values);
+    store_thread($current_forum, $values);
 }
 
 /* FOOTER */

+ 3 - 2
main/forum/reply.php

@@ -80,6 +80,7 @@ if ($current_forum['forum_of_group'] != 0) {
 
 /* Breadcrumbs */
 
+$gradebook = null;
 if (isset($_SESSION['gradebook'])){
     $gradebook = Security::remove_XSS($_SESSION['gradebook']);
 }
@@ -142,10 +143,10 @@ $my_action   = isset($_GET['action']) ? Security::remove_XSS($_GET['action']) :
 $my_post     = isset($_GET['post']) ?   Security::remove_XSS($_GET['post']) : '';
 $my_elements = isset($_SESSION['formelements']) ? $_SESSION['formelements'] : '';
 
-$values      = show_add_post_form($my_action, $my_post, $my_elements); // Note: This has to be cleaned first.
+$values = show_add_post_form($current_forum, $forum_setting, $my_action, $my_post, $my_elements);
 
 if (!empty($values) AND isset($_POST['SubmitPost'])) {
-    $result = store_reply($values);
+    $result = store_reply($current_forum, $values);
     //@todo split the show_add_post_form function
 
     $url = 'viewthread.php?forum='.$current_thread['forum_id'].'&gradebook='.$gradebook.'&thread='.intval($_GET['thread']).'&gidReq='.api_get_group_id().'&origin='.$origin.'&msg='.$result['msg'].'&type='.$result['type'];

+ 55 - 34
main/forum/viewforum.php

@@ -56,7 +56,7 @@ $userid  = api_get_user_id();
 
 /* MAIN DISPLAY SECTION */
 
-$group_id = api_get_group_id();
+$groupId = api_get_group_id();
 
 $my_forum = isset($_GET['forum']) ? $_GET['forum'] : '';
 
@@ -70,25 +70,28 @@ $current_forum_category = get_forumcategory_information($current_forum['forum_ca
 
 $is_group_tutor = false;
 
-if (!empty($group_id)) {
+if (!empty($groupId)) {
     //Group info & group category info
-    $group_properties           = GroupManager::get_group_properties($group_id);
+    $group_properties = GroupManager::get_group_properties($groupId);
         
     //User has access in the group?
-    $user_has_access_in_group   = GroupManager::user_has_access($userid, $group_id, GroupManager::GROUP_TOOL_FORUM);
+    $user_has_access_in_group   = GroupManager::user_has_access($userid, $groupId, GroupManager::GROUP_TOOL_FORUM);
     
-    $is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
+    $is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $groupId);
         
     //Course
     if (!api_is_allowed_to_edit(false, true) AND  //is a student
-        (($current_forum_category && $current_forum_category['visibility'] == 0) OR $current_forum['visibility'] == 0 OR !$user_has_access_in_group)            
+        (($current_forum_category && $current_forum_category['visibility'] == 0) OR
+        $current_forum['visibility'] == 0 OR !$user_has_access_in_group)
     ) {
         api_not_allowed();
     }
 } else {
     //Course
     if (!api_is_allowed_to_edit(false, true) AND  //is a student
-        (($current_forum_category && $current_forum_category['visibility'] == 0) OR $current_forum['visibility'] == 0) //forum category or forum visibility is false
+        (($current_forum_category && $current_forum_category['visibility'] == 0) OR
+            $current_forum['visibility'] == 0
+        ) //forum category or forum visibility is false
     ) {
         api_not_allowed();
     }
@@ -99,6 +102,7 @@ if (!empty($group_id)) {
 $my_search = isset($_GET['search']) ? $_GET['search'] : '';
 $my_action = isset($_GET['action']) ? $_GET['action'] : '';
 
+$gradebook = null;
 if (isset($_SESSION['gradebook'])){
     $gradebook = $_SESSION['gradebook'];
 }
@@ -114,15 +118,16 @@ if (!empty($_GET['gidReq'])) {
     $toolgroup = Database::escape_string($_GET['gidReq']);
     Session::write('toolgroup',$toolgroup);
 }
+$forumUrl = api_get_path(WEB_CODE_PATH).'forum/';
 
 if ($origin == 'group') {    
     
-    $interbreadcrumb[] = array('url' => '../group/group.php', 'name' => get_lang('Groups'));
-    $interbreadcrumb[] = array('url'=>'../group/group_space.php?gidReq='.$_SESSION['toolgroup'], 'name'=> get_lang('GroupSpace').' '.$group_properties['name']);
+    $interbreadcrumb[] = array('url' => api_get_path(WEB_CODE_PATH).'group/group.php', 'name' => get_lang('Groups'));
+    $interbreadcrumb[] = array('url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(), 'name'=> get_lang('GroupSpace').' '.$group_properties['name']);
     $interbreadcrumb[] = array('url' => '#', 'name' => get_lang('Forum').' '.Security::remove_XSS($current_forum['forum_title']));
 } else {
-    $interbreadcrumb[] = array('url' => 'index.php?gradebook='.$gradebook.'&amp;search='.Security::remove_XSS($my_search), 'name' => get_lang('ForumCategories'));
-    $interbreadcrumb[] = array('url' => 'viewforumcategory.php?forumcategory='.$current_forum_category['cat_id'].'&amp;search='.Security::remove_XSS(urlencode($my_search)), 'name' => prepare4display($current_forum_category['cat_title']));
+    $interbreadcrumb[] = array('url' => $forumUrl.'index.php?search='.Security::remove_XSS($my_search), 'name' => get_lang('ForumCategories'));
+    $interbreadcrumb[] = array('url' => $forumUrl.'viewforumcategory.php?forumcategory='.$current_forum_category['cat_id'].'&amp;search='.Security::remove_XSS(urlencode($my_search)), 'name' => prepare4display($current_forum_category['cat_title']));
     $interbreadcrumb[] = array('url' => '#', 'name' => Security::remove_XSS($current_forum['forum_title']));
 }
 
@@ -194,13 +199,19 @@ if ($my_action == 'liststd' AND isset($_GET['content']) AND isset($_GET['id']) A
     if ($nrorow3 > 0 || $nrorow3 == -2) {
         $url = 'cidReq='.Security::remove_XSS($_GET['cidReq']).'&amp;forum='.Security::remove_XSS($my_forum).'&amp;action='.Security::remove_XSS($_GET['action']).'&amp;content='.Security::remove_XSS($_GET['content'],STUDENT).'&amp;id='.intval($_GET['id']);
         $tabs = array(
-                        array('content' =>  get_lang('AllStudents'),
-                               'url'    =>   'viewforum.php?'.$url.'&amp;origin='.$origin.'&amp;list=all'),
-                        array('content' =>  get_lang('StudentsQualified'),
-                               'url'    =>   'viewforum.php?'.$url.'&amp;origin='.$origin.'&amp;list=qualify'),
-                        array('content' =>  get_lang('StudentsNotQualified'),
-                               'url'    =>   'viewforum.php?'.$url.'&amp;origin='.$origin.'&amp;list=notqualify'),
-            );
+            array(
+                'content' =>  get_lang('AllStudents'),
+                'url'    =>   $forumUrl.'viewforum.php?'.$url.'&amp;origin='.$origin.'&amp;list=all'
+            ),
+            array(
+                'content' =>  get_lang('StudentsQualified'),
+                'url'    =>   $forumUrl.'viewforum.php?'.$url.'&amp;origin='.$origin.'&amp;list=qualify'
+            ),
+            array(
+                'content' =>  get_lang('StudentsNotQualified'),
+                'url'    =>   $forumUrl.'viewforum.php?'.$url.'&amp;origin='.$origin.'&amp;list=notqualify'
+            ),
+        );
         $table_list .= Display::tabs_only_link($tabs, $active);
 
         $icon_qualify = 'blog_new.gif';
@@ -227,13 +238,16 @@ if ($my_action == 'liststd' AND isset($_GET['content']) AND isset($_GET['id']) A
                     $class_stdlist = 'row_even';
                 }
                 $name_user_theme = api_get_person_name($row_student_list['firstname'], $row_student_list['lastname']);
-                $table_list .= '<tr class="'.$class_stdlist.'"><td><a href="../user/userInfo.php?uInfo='.$row_student_list['user_id'].'&amp;tipo=sdtlist&amp;'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).$origin_string.'">'.$name_user_theme.'</a></td>';
+                $table_list .= '<tr class="'.$class_stdlist.'"><td>
+                    <a href="'.api_get_path(WEB_CODE_PATH).'user/userInfo.php?uInfo='.$row_student_list['user_id'].'&amp;tipo=sdtlist&amp;'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).$origin_string.'">
+                    '.$name_user_theme.'</a></td>';
                 if ($_GET['list'] == 'qualify') {
                     $table_list .= '<td>'.$row_student_list['qualify'].'/'.$max_qualify.'</td>';
                 }
                 if (api_is_allowed_to_edit(null, true)) {
                     $current_qualify_thread = show_qualify('1', $row_student_list['user_id'], $_GET['id']);
-                    $table_list .= '<td><a href="forumqualify.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;thread='.Security::remove_XSS($_GET['id']).'&amp;user='.$row_student_list['user_id'].'&amp;user_id='.$row_student_list['user_id'].'&amp;idtextqualify='.$current_qualify_thread.'&amp;origin='.$origin.'">'.Display::return_icon($icon_qualify, get_lang('Qualify')).'</a></td></tr>';
+                    $table_list .= '<td><a href="'.$forumUrl.'forumqualify.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;thread='.Security::remove_XSS($_GET['id']).'&amp;user='.$row_student_list['user_id'].'&amp;user_id='.$row_student_list['user_id'].'&amp;idtextqualify='.$current_qualify_thread.'&amp;origin='.$origin.'">'.
+                        Display::return_icon($icon_qualify, get_lang('Qualify')).'</a></td></tr>';
                 }
                 $counter_stdlist++;
             }
@@ -269,10 +283,10 @@ echo '<div class="actions">';
 if ($origin != 'learnpath') {
     
     if ($origin=='group') {
-        echo '<a href="../group/group_space.php?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'">'.Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('Groups'),'',ICON_SIZE_MEDIUM).'</a>';
+        echo '<a href='.api_get_path(WEB_CODE_PATH).'"group/group_space.php?'.api_get_cidreq().'&amp;gradebook='.$gradebook.'">'.Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('Groups'),'',ICON_SIZE_MEDIUM).'</a>';
     } else {
         echo '<span style="float:right;">'.search_link().'</span>';
-        echo '<a href="index.php">'.Display::return_icon('back.png', get_lang('BackToForumOverview'), '', ICON_SIZE_MEDIUM).'</a>';
+        echo '<a href="'.$forumUrl.'index.php">'.Display::return_icon('back.png', get_lang('BackToForumOverview'), '', ICON_SIZE_MEDIUM).'</a>';
     }    
 }
 
@@ -285,10 +299,10 @@ if (api_is_allowed_to_edit(false, true) OR ($current_forum['allow_new_threads']
 	if ($current_forum['locked'] <> 1 AND $current_forum['locked'] <> 1) {
 		if (!api_is_anonymous()) {
 			if ($my_forum == strval(intval($my_forum))) {
-				echo '<a href="newthread.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).$origin_string.'">'.Display::return_icon('new_thread.png',get_lang('NewTopic'),'',ICON_SIZE_MEDIUM).'</a>';
+				echo '<a href="'.$forumUrl.'newthread.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).$origin_string.'">'.Display::return_icon('new_thread.png',get_lang('NewTopic'),'',ICON_SIZE_MEDIUM).'</a>';
 		    } else {
 		    	$my_forum = strval(intval($my_forum));
-				echo '<a href="newthread.php?'.api_get_cidreq().'&amp;forum='.$my_forum.$origin_string.'">'.Display::return_icon('new_thread.png',get_lang('NewTopic'),'',ICON_SIZE_MEDIUM).'</a>';
+				echo '<a href="'.$forumUrl.'newthread.php?'.api_get_cidreq().'&amp;forum='.$my_forum.$origin_string.'">'.Display::return_icon('new_thread.png',get_lang('NewTopic'),'',ICON_SIZE_MEDIUM).'</a>';
 			}
 		}
 	} else {
@@ -336,7 +350,7 @@ $counter = 0;
 if (is_array($threads)) {
     foreach ($threads as $row) {
         // Thread who have no replies yet and the only post is invisible should not be displayed to students.
-        if (api_is_allowed_to_edit(false, true) OR !($row['thread_replies'] == '0' AND $row['visible'] == '0')) {
+        if (api_is_allowed_to_edit(false, true) OR !($row['thread_replies'] == '0' AND $row['visibility'] == '0')) {
             if ($counter % 2 == 0) {
                  $class = 'row_odd';
             } else {
@@ -356,7 +370,7 @@ if (is_array($threads)) {
             }
             echo '</td>';
             echo '<td>';
-            echo '<a href="viewthread.php?'.api_get_cidreq().'&amp;gradebook='.Security::remove_XSS($_GET['gradebook']).'&amp;forum='.Security::remove_XSS($my_forum).'&amp;origin='.$origin.'&amp;thread='.$row['thread_id'].$origin_string.'&amp;search='.Security::remove_XSS(urlencode($my_search)).'" '.class_visible_invisible($row['visibility']).'>'.prepare4display($row['thread_title']).'</a></td>';
+            echo '<a href="viewthread.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;origin='.$origin.'&amp;thread='.$row['thread_id'].$origin_string.'&amp;search='.Security::remove_XSS(urlencode($my_search)).'" '.class_visible_invisible($row['visibility']).'>'.prepare4display($row['thread_title']).'</a></td>';
             echo '<td>'.$row['thread_replies'].'</td>';
             echo '<td>'.$row['thread_views'].'</td>';
             // display the author name
@@ -375,7 +389,7 @@ if (is_array($threads)) {
             if ($last_post_info) {
                 $poster_info = api_get_user_info($last_post_info['poster_id']);                                
                 $post_date = api_convert_and_format_date($last_post_info['post_date']);
-                $last_post = $post_date.' '.get_lang('By').' '.display_user_link($last_post_info['poster_id'], $poster_info['complete_name'], '', $poster_info['user_name']);        
+                $last_post = $post_date.' '.get_lang('By').' '.display_user_link($last_post_info['poster_id'], $poster_info['complete_name'], '', $poster_info['username']);
             }
             /*
             if ($row['last_poster_user_id'] == '0') {
@@ -408,7 +422,9 @@ if (is_array($threads)) {
             echo '<td>'.$last_post.'</td>';
             echo '<td class="td_actions">';
             // Get attachment id.
+            if (isset($row['post_id'])) {
             $attachment_list = get_attachment($row['post_id']);
+            }
             $id_attach = !empty($attachment_list) ? $attachment_list['id'] : '';
 
             $sql_post_id = "SELECT post_id FROM $table_posts WHERE c_id = $course_id AND post_title='".Database::escape_string($row['thread_title'])."'";
@@ -417,17 +433,20 @@ if (is_array($threads)) {
 
             if ($origin != 'learnpath') {
                 if (api_is_allowed_to_edit(false, true) && !(api_is_course_coach() && $current_forum['session_id'] != $_SESSION['id_session'])) {
-                    echo '<a href="editpost.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;thread='.Security::remove_XSS($row['thread_id']).'&amp;post='.$row_post_id['post_id'].'&amp;gidReq='.$_SESSION['toolgroup'].'&amp;origin='.$origin.'&amp;id_attach='.$id_attach.'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
+                    echo '<a href="'.$forumUrl.'editpost.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;thread='.Security::remove_XSS($row['thread_id']).'&amp;post='.$row_post_id['post_id'].'&id_attach='.$id_attach.'">'.
+                        Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
                     
                     if (api_resource_is_locked_by_gradebook($row['thread_id'], LINK_FORUM_THREAD)) {
                         echo Display::return_icon('delete_na.png', get_lang('ResourceLockedByGradebook'), array(), ICON_SIZE_SMALL);
                     } else {
-                        echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;action=delete&amp;content=thread&amp;gidReq='.$_SESSION['toolgroup'].'&amp;id='.$row['thread_id'].$origin_string."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeleteCompleteThread'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a>';
+                        echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;action=delete&amp;content=thread&id='.$row['thread_id'].$origin_string."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeleteCompleteThread'), ENT_QUOTES))."')) return false;\">".
+                            Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL).'</a>';
                     }
                     
-                    display_visible_invisible_icon('thread', $row['thread_id'], $row['visibility'], array('forum' => $my_forum, 'origin' => $origin, 'gidReq' => $_SESSION['toolgroup']));
-                    display_lock_unlock_icon('thread', $row['thread_id'], $row['locked'], array('forum' => $my_forum, 'origin' => $origin, 'gidReq' => $_SESSION['toolgroup']));
-                    echo '<a href="viewforum.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;action=move&amp;gidReq='.$_SESSION['toolgroup'].'&amp;thread='.$row['thread_id'].$origin_string.'">'.Display::return_icon('move.png', get_lang('MoveThread'), array(), ICON_SIZE_SMALL).'</a>';
+                    display_visible_invisible_icon('thread', $row['thread_id'], $row['visibility'], array('forum' => $my_forum, 'origin' => $origin, 'gidReq' => $groupId));
+                    display_lock_unlock_icon('thread', $row['thread_id'], $row['locked'], array('forum' => $my_forum, 'origin' => $origin, 'gidReq' => api_get_group_id()));
+                    echo '<a href="viewforum.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;action=move&thread='.$row['thread_id'].$origin_string.'">'.
+                        Display::return_icon('move.png', get_lang('MoveThread'), array(), ICON_SIZE_SMALL).'</a>';
                 }
             }
             $iconnotify = 'send_mail.gif';
@@ -438,11 +457,13 @@ if (is_array($threads)) {
             }
             $icon_liststd = 'user.png';
             if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
-                echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;origin='.$origin.'&amp;action=notify&amp;content=thread&amp;gidReq='.$_SESSION['toolgroup'].'&amp;id='.$row['thread_id'].'">'.Display::return_icon($iconnotify, get_lang('NotifyMe')).'</a>';
+                echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;origin='.$origin.'&amp;action=notify&amp;content=thread&id='.$row['thread_id'].'">'.
+                    Display::return_icon($iconnotify, get_lang('NotifyMe')).'</a>';
             }
 
             if (api_is_allowed_to_edit(null,true) && $origin != 'learnpath') {
-                echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;origin='.$origin.'&amp;action=liststd&amp;content=thread&amp;gidReq='.$_SESSION['toolgroup'].'&amp;id='.$row['thread_id'].'">'.Display::return_icon($icon_liststd,get_lang('StudentList'), array(), ICON_SIZE_SMALL).'</a>';
+                echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($my_forum).'&amp;origin='.$origin.'&amp;action=liststd&amp;content=thread&id='.$row['thread_id'].'">'.
+                    Display::return_icon($icon_liststd,get_lang('StudentList'), array(), ICON_SIZE_SMALL).'</a>';
             }
             echo '</td></tr>';
         }

+ 1 - 1
main/forum/viewforumcategory.php

@@ -93,7 +93,7 @@ if ($origin=='learnpath') {
 
 /* ACTIONS */
 
-$whatsnew_post_info = $_SESSION['whatsnew_post_info'];
+$whatsnew_post_info = isset($_SESSION['whatsnew_post_info']) ? $_SESSION['whatsnew_post_info'] : null;
 
 /* Is the user allowed here? */
 

+ 5 - 3
main/forum/viewpost.php

@@ -22,9 +22,11 @@ require 'forumconfig.inc.php';
 require_once 'forumfunction.inc.php';
 
 $htmlHeadXtra[] = '<script language="javascript">
-                                        $(document).ready(function(){ $(\'.hide-me\').slideUp() });
-                                    function hidecontent(content){ $(content).slideToggle(\'normal\'); }
-                                    </script>';
+$(document).ready(function(){ $(\'.hide-me\').slideUp() });
+	function hidecontent(content){
+	$(content).slideToggle(\'normal\');
+	}
+</script>';
 
 // Are we in a lp ?
 $origin = '';

+ 13 - 34
main/forum/viewthread.php

@@ -23,12 +23,15 @@ require_once 'forumconfig.inc.php';
 require_once 'forumfunction.inc.php';
 
 $nameTools = get_lang('Forum');
+$forumUrl = api_get_path(WEB_CODE_PATH).'forum/';
 
 // Are we in a lp ?
 $origin = '';
 if (isset($_GET['origin'])) {
     $origin =  Security::remove_XSS($_GET['origin']);
 }
+$my_search = null;
+$gradebook = null;
 
 /* MAIN DISPLAY SECTION */
 
@@ -42,7 +45,7 @@ $current_thread	= get_thread_information($_GET['thread']); // Nnote: This has to
 $current_forum	= get_forum_information($current_thread['forum_id']); // Note: This has to be validated that it is an existing forum.
 $current_forum_category	= get_forumcategory_information($current_forum['forum_category']);
 
-$whatsnew_post_info	= $_SESSION['whatsnew_post_info']; // This variable should be deprecated?
+$whatsnew_post_info	= isset($_SESSION['whatsnew_post_info']) ? $_SESSION['whatsnew_post_info'] : null; // This variable should be deprecated?
 
 /* Header and Breadcrumbs */
 
@@ -59,7 +62,7 @@ if (!empty($gradebook) && $gradebook == 'view') {
 }
 
 if ($origin == 'group') {
-    $session_toolgroup = intval($_SESSION['toolgroup']);
+    $session_toolgroup = api_get_group_id();
     $group_properties = GroupManager :: get_group_properties($session_toolgroup);
     $interbreadcrumb[] = array('url'=>'../group/group.php', 'name' => get_lang('Groups'));
     $interbreadcrumb[] = array('url'=>'../group/group_space.php?gidReq='.$session_toolgroup, 'name'=> get_lang('GroupSpace').' '.$group_properties['name']);
@@ -130,14 +133,8 @@ if ($my_message != 'PostDeletedSpecial') {
     echo '<span style="float:right;">'.search_link().'</span>';
     if ($origin != 'learnpath') {
 
-        /*if ($origin == 'group') {
-            echo '<a href="../group/group_space.php?'.api_get_cidreq().'&amp;gidReq='.Security::remove_XSS($_GET['gidReq']).'&amp;gradebook='.$gradebook.'">'.Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('Groups'), '', ICON_SIZE_MEDIUM).'</a>';
-            echo '<a href="viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&amp;gidReq='.$session_toolgroup.'&amp;origin='.$origin.'">'.Display::return_icon('forum.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM).'</a>';
-        } else {
-            echo '<a href="index.php?gradebook='.$gradebook.'">'.Display::return_icon('back.png', get_lang('BackToForumOverview'), '', ICON_SIZE_MEDIUM).'</a>';
-            echo '<a href="viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&amp;gidReq='.$session_toolgroup.'">'.Display::return_icon('forum.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM).'</a>';
-        }*/
-        echo '<a href="viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&amp;gidReq='.$session_toolgroup.'&amp;origin='.$origin.'">'.Display::return_icon('back.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM).'</a>';
+        echo '<a href="'.$forumUrl.'viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&'.api_get_cidreq().'">'.
+            Display::return_icon('back.png', get_lang('BackToForum'), '', ICON_SIZE_MEDIUM).'</a>';
 
     }
     // The reply to thread link should only appear when the forum_category is not locked AND the forum is not locked AND the thread is not locked.
@@ -147,18 +144,13 @@ if ($my_message != 'PostDeletedSpecial') {
         if ($_user['user_id'] OR ($current_forum['allow_anonymous'] == 1 AND !$_user['user_id'])) {
             // reply link
             if (!api_is_anonymous() && api_is_allowed_to_session_edit(false, true)) {
-                echo '<a href="reply.php?'.api_get_cidreq().'&amp;gidReq='.Security::remove_XSS($_GET['gidReq']).'&amp;forum='.Security::remove_XSS($_GET['forum']).'&amp;thread='.Security::remove_XSS($_GET['thread']).'&amp;action=replythread&amp;origin='.$origin.'">'.Display::return_icon('reply_thread.png', get_lang('ReplyToThread'), '', ICON_SIZE_MEDIUM).'</a>';
+                echo '<a href="'.$forumUrl.'reply.php?'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&thread='.Security::remove_XSS($_GET['thread']).'&amp;action=replythread">'.
+                    Display::return_icon('reply_thread.png', get_lang('ReplyToThread'), '', ICON_SIZE_MEDIUM).'</a>';
             }
             // new thread link
             if ((api_is_allowed_to_edit(false, true) && !(api_is_course_coach() && $current_forum['session_id'] != $_SESSION['id_session'])) OR ($current_forum['allow_new_threads'] == 1 AND isset($_user['user_id'])) OR ($current_forum['allow_new_threads'] == 1 AND !isset($_user['user_id']) AND $current_forum['allow_anonymous'] == 1)) {
                 if ($current_forum['locked'] <> 1 AND $current_forum['locked'] <> 1) {
                     echo '&nbsp;&nbsp;';
-/*					if ( isset($_GET['gradebook']) && $_GET['gradebook'] != '') {
-                        $info_thread = get_thread_information($_GET['thread']);
-                        echo '<a href="newthread.php?'.api_get_cidreq().'&amp;forum='.$info_thread['forum_id'].'&amp;origin='.$origin.'&amp;gradebook='.Security::remove_XSS($_GET['gradebook']).'">'.Display::return_icon('new_thread.png', get_lang('NewTopic'), '', ICON_SIZE_MEDIUM).'</a>';
-                    } else {
-                        echo '<a href="newthread.php?'.api_get_cidreq().'&amp;forum='.Security::remove_XSS($_GET['forum']).'&amp;origin='.$origin.'">'.Display::return_icon('new_thread.png', get_lang('NewTopic'), '', ICON_SIZE_MEDIUM).'</a>';
-                    } */
                 } else {
                     echo get_lang('ForumLocked');
                 }
@@ -168,10 +160,10 @@ if ($my_message != 'PostDeletedSpecial') {
 
     // The different views of the thread.
     if ($origin != 'learnpath') {
-        $my_url = '<a href="viewthread.php?'.api_get_cidreq().'&amp;gidReq='.Security::remove_XSS($_GET['gidReq']).'&amp;forum='.Security::remove_XSS($_GET['forum']).'&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'&amp;thread='.Security::remove_XSS($_GET['thread']).'&amp;search='.Security::remove_XSS(urlencode($my_search));
-        echo $my_url.'&amp;view=flat&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'">'.Display::return_icon('forum_listview.gif', get_lang('FlatView')).get_lang('FlatView').'</a>';
-        echo $my_url.'&amp;view=threaded&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'">'.Display::return_icon('forum_threadedview.gif', get_lang('ThreadedView')).get_lang('ThreadedView').'</a>';
-        echo $my_url.'&amp;view=nested&amp;origin='.$origin.'&amp;gradebook='.$gradebook.'">'.Display::return_icon('forum_nestedview.gif', get_lang('NestedView')).get_lang('NestedView').'</a>';
+        $my_url = '<a href="'.$forumUrl.'viewthread.php?'.api_get_cidreq().'&'.api_get_cidreq().'&forum='.Security::remove_XSS($_GET['forum']).'&thread='.Security::remove_XSS($_GET['thread']).'&search='.Security::remove_XSS(urlencode($my_search));
+        echo $my_url.'&amp;view=flat">'.Display::return_icon('forum_listview.gif', get_lang('FlatView')).get_lang('FlatView').'</a>';
+        echo $my_url.'&amp;view=threaded">'.Display::return_icon('forum_threadedview.gif', get_lang('ThreadedView')).get_lang('ThreadedView').'</a>';
+        echo $my_url.'&amp;view=nested">'.Display::return_icon('forum_nestedview.gif', get_lang('NestedView')).get_lang('NestedView').'</a>';
     }
     $my_url = null;
 
@@ -200,19 +192,6 @@ if ($my_message != 'PostDeletedSpecial') {
     // Note pcool: I tried to use only one sql statement (and function) for this,
     // but the problem is that the visibility of the forum AND forum cateogory are stored in the item_property table.
 
-    /*echo '<table class="forum_table_title" width="100%">';
-
-    // The thread
-    echo '<tr><th style="padding:5px;" align="left" colspan="6">';
-    echo '<div class="forum_title">';
-        echo '<a href="viewforum.php?forum='.Security::remove_XSS($_GET['forum']).'&amp;gidReq='.$session_toolgroup.'&amp;origin='.$origin.'">'.$current_forum['forum_title'].'</a><br />';
-        echo '<span class="forum_description">';
-        echo $current_forum['forum_comment'];
-        echo '</span>';
-    echo '</div>';
-
-    echo '</th></tr>';
-    echo '</table>';*/
     
     if (isset($_GET['msg']) && isset($_GET['type'])) {
     	switch($_GET['type']) {

+ 24 - 9
main/forum/viewthread_nested.inc.php

@@ -67,27 +67,35 @@ foreach ($rows as $post) {
     // The user who posted it can edit his thread only if the course admin allowed this in the properties of the forum
     // The course admin him/herself can do this off course always
     //if (($current_forum['allow_edit']==1 AND $post['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))) {
-    if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR  ($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))) {
+    if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR
+       ($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) OR
+        (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id'] != $_SESSION['id_session']))
+    ) {
         if ($locked == false) {
-            echo "<a href=\"editpost.php?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;origin=".$origin."&amp;post=".$post['post_id']."&amp;id_attach=".$id_attach."\">".Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL)."</a>";
+            echo "<a href=\"editpost.php?".api_get_cidreq()."&forum=".$clean_forum_id."&thread=".$clean_thread_id."&post=".$post['post_id']."&amp;id_attach=".$id_attach."\">".
+                Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL)."</a>";
         }
     }
 
-    if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])) {
+    if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR
+        api_is_allowed_to_edit(false,true) &&
+        !(api_is_course_coach() &&
+        $current_forum['session_id']!=$_SESSION['id_session'])
+    ) {
         if ($locked == false) {
             echo "<a href=\"".api_get_self()."?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;action=delete&amp;content=post&amp;id=".$post['post_id']."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL)."</a>";
         }
     }
 
-    if (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])) {
+    if (api_is_allowed_to_edit(false,true)
+        && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])) {
         display_visible_invisible_icon('post', $post['post_id'], $post['visible'],array('forum'=>$clean_forum_id,'thread'=>$clean_thread_id ));
-        echo "";
         if ($count>0) {
             echo "<a href=\"viewthread.php?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;action=move&amp;origin=".$origin."&amp;post=".$post['post_id']."\">".Display::return_icon('move.png',get_lang('MovePost'), array(),ICON_SIZE_SMALL)."</a>";
         }
     }
     $userinf=api_get_user_info($post['user_id']);
-    $user_status=api_get_status_of_user_in_course($post['user_id'],api_get_course_int_id());
+    $user_status = api_get_status_of_user_in_course($post['user_id'],api_get_course_id());
     if (api_is_allowed_to_edit(null,true)) {
         //if ($count>0 && $user_status!=1) {
         if ($count>0) {
@@ -100,7 +108,9 @@ foreach ($rows as $post) {
     }
     //echo '<br /><br />';
     //if (($current_forum_category['locked']==0 AND $current_forum['locked']==0 AND $current_thread['locked']==0) OR api_is_allowed_to_edit())
-    if (($current_forum_category && $current_forum_category['locked']==0) AND $current_forum['locked']==0 AND $current_thread['locked']==0 OR api_is_allowed_to_edit(false,true)) {
+    if (($current_forum_category && $current_forum_category['locked']==0) AND
+        $current_forum['locked']==0 AND $current_thread['locked']==0 OR api_is_allowed_to_edit(false,true)
+    ) {
         if ($_user['user_id'] OR ($current_forum['allow_anonymous']==1 AND !$_user['user_id'])) {
             if (!api_is_anonymous() && api_is_allowed_to_session_edit(false,true)) {
                 echo '<a href="reply.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;post='.$post['post_id'].'&amp;action=replymessage&amp;origin='. $origin .'">'.Display :: return_icon('message_reply_forum.png', get_lang('ReplyToMessage'))."</a>";
@@ -120,7 +130,10 @@ foreach ($rows as $post) {
     }
     echo "</td>";
     // note: this can be removed here because it will be displayed in the tree
-    if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) and !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) and !empty($whatsnew_post_info[$_GET['forum']][$post['thread_id']])) {
+    if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) AND
+        !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) AND
+        !empty($whatsnew_post_info[$_GET['forum']][$post['thread_id']])
+    ) {
         $post_image=Display::return_icon('forumpostnew.gif');
     } else {
         $post_image=Display::return_icon('forumpost.gif');
@@ -151,7 +164,9 @@ foreach ($rows as $post) {
         echo $realname;
         echo ' "> '.$user_filename.' </a>';
         echo '<span class="forum_attach_comment" >'.$attachment_list['comment'].'</span>';
-        if (($current_forum['allow_edit']==1 AND $post['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])))	{
+        if (($current_forum['allow_edit']==1 AND $post['user_id']==$_user['user_id']) OR
+            (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))
+        ) {
         echo '&nbsp;&nbsp;<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;origin='.Security::remove_XSS($_GET['origin']).'&amp;action=delete_attach&amp;id_attach='.$attachment_list['id'].'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES)).'\')) return false;">'.Display::return_icon('delete.gif',get_lang('Delete')).'</a><br />';
         }
         echo '</td></tr>';

+ 53 - 18
main/forum/viewthread_threaded.inc.php

@@ -27,7 +27,7 @@ $rows = get_posts($_GET['thread']); // Note: This has to be cleaned first.
 $rows = calculate_children($rows);
 
 
-if ($_GET['post']) {
+if (isset($_GET['post']) && $_GET['post']) {
     $display_post_id = intval($_GET['post']); // note: this has to be cleaned first
 } else {
     // we need to display the first post
@@ -65,13 +65,19 @@ foreach ($rows as $post) {
     $indent=$post['indent_cnt']*'20';
     $thread_structure.= "<div style=\"margin-left: ".$indent."px;\">";
 
-    if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) and !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) and !empty($whatsnew_post_info[$_GET['forum']][$post['thread_id']])) {
+    if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) AND
+        !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$post['post_id']]) AND
+        !empty($whatsnew_post_info[$_GET['forum']][$post['thread_id']])
+    ) {
         $post_image=Display::return_icon('forumpostnew.gif');
     } else {
         $post_image=Display::return_icon('forumpost.gif');
     }
     $thread_structure.= $post_image;
-    if ($_GET['post']==$post['post_id'] OR ($counter==1 AND !isset($_GET['post']))) {
+    if (isset($_GET['post']) &&
+        $_GET['post'] == $post['post_id'] OR
+        ($counter==1 AND !isset($_GET['post']))
+    ) {
         $thread_structure.='<strong>'.prepare4display($post['post_title']).'</strong></div>';
         $prev_next_array[]=$post['post_id'];
     } else {
@@ -81,7 +87,8 @@ foreach ($rows as $post) {
             $class='';
         }
         $count_loop=($count==0)?'&amp;id=1' : '';
-        $thread_structure.= "<a href=\"viewthread.php?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;post=".$post['post_id']."&amp;origin=$origin$count_loop\" $class>".prepare4display($post['post_title'])."</a></div>";
+        $thread_structure.= "<a href=\"viewthread.php?".api_get_cidreq()."&forum=".$clean_forum_id."&thread=".$clean_thread_id."&post=".$post['post_id']."&amp;origin=$origin$count_loop\" $class>".
+            prepare4display($post['post_title'])."</a></div>";
         $prev_next_array[]=$post['post_id'];
     }
     $count++;
@@ -103,16 +110,32 @@ $next_message=get_lang('NextMessage');
 $prev_message=get_lang('PrevMessage');
 
 // images
-$first_img 	= Display::return_icon('action_first.png',get_lang('FirstMessage'), array('style' => 'vertical-align: middle;'));
-$last_img 	= Display::return_icon('action_last.png',get_lang('LastMessage'), array('style' => 'vertical-align: middle;'));
-$prev_img 	= Display::return_icon('action_prev.png',get_lang('PrevMessage'), array('style' => 'vertical-align: middle;'));
-$next_img 	= Display::return_icon('action_next.png',get_lang('NextMessage'), array('style' => 'vertical-align: middle;'));
+$first_img = Display::return_icon(
+    'action_first.png',
+    get_lang('FirstMessage'),
+    array('style' => 'vertical-align: middle;')
+);
+$last_img = Display::return_icon(
+    'action_last.png',
+    get_lang('LastMessage'),
+    array('style' => 'vertical-align: middle;')
+);
+$prev_img = Display::return_icon(
+    'action_prev.png',
+    get_lang('PrevMessage'),
+    array('style' => 'vertical-align: middle;')
+);
+$next_img = Display::return_icon(
+    'action_next.png',
+    get_lang('NextMessage'),
+    array('style' => 'vertical-align: middle;')
+);
 
 // links
-$first_href = 'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&amp;origin='.$origin.'&amp;id=1&amp;post='.$prev_next_array[0];
-$last_href 	= 'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&amp;origin='.$origin.'&amp;post='.$prev_next_array[$max-1];
-$prev_href	= 'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&amp;origin='.$origin.'&amp;post='.$prev_next_array[$prev_id];
-$next_href	= 'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&amp;origin='.$origin.'&amp;post='.$prev_next_array[$next_id];
+$first_href = $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&id=1&amp;post='.$prev_next_array[0];
+$last_href 	= $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&post='.$prev_next_array[$max-1];
+$prev_href	= $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&post='.$prev_next_array[$prev_id];
+$next_href	= $forumUrl.'viewthread.php?'.api_get_cidreq().'&amp;forum='.$clean_forum_id.'&amp;thread='.$clean_thread_id.'&amp;gradebook='.$gradebook.'&post='.$prev_next_array[$next_id];
 
 echo '<center style="margin-top: 10px; margin-bottom: 10px;">';
 //go to: first and previous
@@ -163,7 +186,9 @@ if ($rows[$display_post_id]['user_id']=='0') {
     $name=api_get_person_name($rows[$display_post_id]['firstname'], $rows[$display_post_id]['lastname']);
 }
 
-if (api_get_course_setting('allow_user_image_forum')) {echo '<br />'.display_user_image($rows[$display_post_id]['user_id'],$name, $origin).'<br />';	}
+if (api_get_course_setting('allow_user_image_forum')) {
+    echo '<br />'.display_user_image($rows[$display_post_id]['user_id'],$name, $origin).'<br />';
+}
 echo display_user_link($rows[$display_post_id]['user_id'], $name, $origin, $username)."<br />";
 echo api_convert_and_format_date($rows[$display_post_id]['post_date']).'<br /><br />';
 // get attach id
@@ -175,13 +200,17 @@ $id_attach = !empty($attachment_list)?$attachment_list['id']:'';
 //if (($current_forum['allow_edit']==1 AND $rows[$display_post_id]['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true) && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))) {
 if ( GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR  ($current_forum['allow_edit']==1 AND $row['user_id']==$_user['user_id']) or (api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session']))) {
     if ($locked == false) {
-        echo "<a href=\"editpost.php?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;origin=".$origin."&amp;post=".$rows[$display_post_id]['post_id']."&amp;id_attach=".$id_attach."\">".Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL)."</a>";
+        echo "<a href=\"editpost.php?".api_get_cidreq()."&forum=".$clean_forum_id."&thread=".$clean_thread_id."&post=".$rows[$display_post_id]['post_id']."&amp;id_attach=".$id_attach."\">".
+            Display::return_icon('edit.png',get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>';
     }
 }
 
-if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR api_is_allowed_to_edit(false,true)  && !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])) {
+if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR
+    api_is_allowed_to_edit(false,true) &&
+    !(api_is_course_coach() && $current_forum['session_id']!=$_SESSION['id_session'])
+) {
     if ($locked == false) {
-        echo "<a href=\"".api_get_self()."?".api_get_cidreq()."&amp;gidReq=".Security::remove_XSS($_GET['gidReq'])."&amp;forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;action=delete&amp;content=post&amp;id=".$rows[$display_post_id]['post_id']."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL)."</a>";
+        echo "<a href=\"".api_get_self()."?".api_get_cidreq()."&forum=".$clean_forum_id."&amp;thread=".$clean_thread_id."&amp;action=delete&amp;content=post&amp;id=".$rows[$display_post_id]['post_id']."\" onclick=\"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('DeletePost'), ENT_QUOTES))."')) return false;\">".Display::return_icon('delete.png',get_lang('Delete'), array(), ICON_SIZE_SMALL)."</a>";
     }
     display_visible_invisible_icon('post', $rows[$display_post_id]['post_id'], $rows[$display_post_id]['visible'],array('forum'=>$clean_forum_id,'thread'=>$clean_thread_id, 'post'=>Security::remove_XSS($_GET['post']) ));
     echo "";
@@ -203,7 +232,10 @@ if (GroupManager::is_tutor_of_group(api_get_user_id(), $group_id) OR api_is_allo
     }
 }
 $userinf=api_get_user_info($rows[$display_post_id]['user_id']);
-$user_status=api_get_status_of_user_in_course($rows[$display_post_id]['user_id'],api_get_course_int_id());
+$user_status = api_get_status_of_user_in_course(
+    $rows[$display_post_id]['user_id'],
+    api_get_course_id()
+);
 if (api_is_allowed_to_edit(null,true)) {
     if ($post_id > $post_minor ) {
         //if ($user_status!=1) {
@@ -235,7 +267,10 @@ if (($current_forum_category && $current_forum_category['locked']==0) AND $curre
 }
 echo "</td>";
 // note: this can be removed here because it will be displayed in the tree
-if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]) and !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]) and !empty($whatsnew_post_info[$_GET['forum']][$rows[$display_post_id]['thread_id']])) {
+if (isset($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]) AND
+    !empty($whatsnew_post_info[$current_forum['forum_id']][$current_thread['thread_id']][$rows[$display_post_id]['post_id']]) AND
+    !empty($whatsnew_post_info[$_GET['forum']][$rows[$display_post_id]['thread_id']])
+) {
     $post_image=Display::return_icon('forumpostnew.gif');
 } else {
     $post_image=Display::return_icon('forumpost.gif');

+ 10 - 2
main/gradebook/exercise_jump.php

@@ -26,17 +26,25 @@ $gradebook = Security::remove_XSS($_GET['gradebook']);
 $session_id = api_get_session_id();
 
 $cidReq = Security::remove_XSS($_GET['cidReq']);
+$type = Security::remove_XSS($_GET['type']);
+
+$doExerciseUrl = api_get_path(WEB_CODE_PATH).'exercice/overview.php?session_id='.$session_id.'&cidReq='.$cidReq.'&gradebook='.$gradebook.'&origin=&learnpath_id=&learnpath_item_id=&exerciseId='.intval($_GET['doexercise']);
+
+// no support for hot potatoes
+if ($type == LINK_HOTPOTATOES) {
+    $doExerciseUrl = api_get_path(WEB_CODE_PATH).'exercice/exercice.php?session_id='.$session_id.'&cidReq='.Security::remove_XSS($cidReq);
+}
 
 $_course['name'] = $course_title;
 $_course['official_code'] = $course_code;
 
 if (isset($_GET['doexercise'])) {
-	header('Location: ../exercice/overview.php?session_id='.$session_id.'&cidReq='.$cidReq.'&gradebook='.$gradebook.'&origin=&learnpath_id=&learnpath_item_id=&exerciseId='.intval($_GET['doexercise']));
+	header('Location: '.$doExerciseUrl);
 	exit;
 } else {
 	if (isset($_GET['gradebook'])) {
 		$add_url = '&gradebook=view&exerciseId='.intval($_GET['exerciseId']);
 	}
-	header('Location: ../exercice/exercice.php??session_id='.$session_id.'&cidReq='.Security::remove_XSS($cidReq).'&show=result'.$add_url);
+	header('Location: '.api_get_path(WEB_CODE_PATH).'exercice/overview.php?session_id='.$session_id.'&cidReq='.Security::remove_XSS($cidReq).'&'.$add_url);
 	exit;
 }

+ 10 - 2
main/gradebook/gradebook_add_cat.php

@@ -95,7 +95,13 @@ if ($_in_course) {
 
 $catadd->set_course_code(api_get_course_id());
 
-$form = new CatForm(CatForm :: TYPE_ADD, $catadd, 'add_cat_form', null, api_get_self() . '?selectcat='.$get_select_cat);
+$form = new CatForm(
+    CatForm :: TYPE_ADD,
+    $catadd,
+    'add_cat_form',
+    null,
+    api_get_self() . '?selectcat='.$get_select_cat.'&'.api_get_cidreq()
+);
 
 if ($form->validate()) {
 	$values = $form->exportValues();
@@ -113,6 +119,7 @@ if ($form->validate()) {
 		$cat->set_name($values['name']);
 		$cat->set_course_code($values['course_code']);//?
 	}
+    $cat->set_session_id(api_get_session_id());
 	//Always add the gradebook to the course
 	$cat->set_course_code(api_get_course_id());
 
@@ -151,7 +158,8 @@ $display_form = true;
         $display_form = false;
     }
 }*/
-if ($display_form)
+if ($display_form) {
     $form->display();
+}
 
 Display :: display_footer();

+ 25 - 10
main/gradebook/gradebook_add_link.php

@@ -7,7 +7,7 @@
 /**
  * Init
  */
-$language_file = 'gradebook';
+$language_file = array('gradebook', 'exercice');
 //$cidReset = true;
 require_once '../inc/global.inc.php';
 require_once 'lib/be.inc.php';
@@ -27,29 +27,43 @@ $tbl_forum_thread = Database :: get_course_table(TABLE_FORUM_THREAD);
 $tbl_link = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
 
 $session_id = api_get_session_id();
+$typeSelected = isset($_GET['typeselected']) ? intval($_GET['typeselected']) : null;
+
+if ($session_id == 0) {
 $all_categories = Category :: load(null, null, api_get_course_id(), null, null, $session_id);
 
+} else {
+    $all_categories = Category::load_session_categories(null, $session_id);
+}
 $category = Category :: load($_GET['selectcat']);
-$url = api_get_self().'?selectcat='.Security::remove_XSS($_GET['selectcat']).'&newtypeselected='.(isset($_GET['typeselected']) ? Security::remove_XSS($_GET['typeselected']) : '').'&course_code='.api_get_course_id();
-$typeform = new LinkForm(LinkForm :: TYPE_CREATE, $category[0], null, 'create_link', null, $url, $_GET['typeselected']);
+$url = api_get_self().'?selectcat='.Security::remove_XSS($_GET['selectcat']).'&newtypeselected='.$typeSelected.'&course_code='.api_get_course_id();
+$typeform = new LinkForm(LinkForm :: TYPE_CREATE, $category[0], null, 'create_link', null, $url, $typeSelected);
 
 // if user selected a link type
 if ($typeform->validate() && isset($_GET['newtypeselected'])) {
     // reload page, this time with a parameter indicating the selected type
     header('Location: '.api_get_self().'?selectcat='.Security::remove_XSS($_GET['selectcat'])
         .'&typeselected='.$typeform->exportValue('select_link')
-        .'&course_code='.Security::remove_XSS($_GET['course_code']));
+        .'&course_code='.Security::remove_XSS($_GET['course_code'])).'&'.api_get_cidreq();
     exit;
 }
 
 // link type selected, show 2nd form to retrieve the link data
-if (isset($_GET['typeselected']) && $_GET['typeselected'] != '0') {
-    $url = api_get_self().'?selectcat='.Security::remove_XSS($_GET['selectcat']).'&typeselected='.Security::remove_XSS($_GET['typeselected']).'&course_code='.Security::remove_XSS($_GET['course_code']);
-    $addform = new LinkAddEditForm(LinkAddEditForm :: TYPE_ADD, $all_categories, intval($_GET['typeselected']), null, 'add_link', $url);
+if (isset($typeSelected) && $typeSelected != '0') {
+    $url = api_get_self().'?selectcat='.Security::remove_XSS($_GET['selectcat']).'&typeselected='.$typeSelected.'&course_code='.$courseCode.'&'.api_get_cidreq();
+
+    $addform = new LinkAddEditForm(
+        LinkAddEditForm :: TYPE_ADD,
+        $all_categories,
+        $typeSelected,
+        null,
+        'add_link',
+        $url
+    );
 
     if ($addform->validate()) {
         $addvalues = $addform->exportValues();
-        $link = LinkFactory :: create($_GET['typeselected']);
+        $link = LinkFactory :: create($typeSelected);
         $link->set_user_id(api_get_user_id());
         $link->set_course_code(api_get_course_id());
 
@@ -76,14 +90,15 @@ if (isset($_GET['typeselected']) && $_GET['typeselected'] != '0') {
         $link->set_visible(empty($addvalues['visible']) ? 0 : 1);
 
         //update view_properties
-        if (isset($_GET['typeselected']) && 5 == $_GET['typeselected'] && (isset($addvalues['select_link']) && $addvalues['select_link'] <> "")) {
+        if (isset($typeSelected) && 5 == $typeSelected && (isset($addvalues['select_link']) && $addvalues['select_link'] <> "")) {
 
             $sql1 = 'SELECT thread_title from '.$tbl_forum_thread.'
 					 WHERE c_id = '.$course_info['real_id'].' AND thread_id='.$addvalues['select_link'];
             $res1 = Database::query($sql1);
             $rowtit = Database::fetch_row($res1);
             $course_id = api_get_course_id();
-            $sql_l = 'SELECT count(*) FROM '.$tbl_link.' WHERE ref_id='.$addvalues['select_link'].' and course_code="'.$course_id.'" and type=5;';
+            $sql_l = 'SELECT count(*) FROM '.$tbl_link.'
+                      WHERE ref_id='.$addvalues['select_link'].' and course_code="'.$course_id.'" and type=5;';
             $res_l = Database::query($sql_l);
             $row = Database::fetch_row($res_l);
             if ($row[0] == 0) {

+ 2 - 1
main/gradebook/gradebook_add_result.php

@@ -24,7 +24,8 @@ block_students();
 $resultadd = new Result();
 $resultadd->set_evaluation_id($_GET['selecteval']);
 $evaluation = Evaluation :: load($_GET['selecteval']);
-$add_result_form = new EvalForm(EvalForm :: TYPE_RESULT_ADD, $evaluation[0], $resultadd, 'add_result_form', null, api_get_self() . '?selectcat=' . Security::remove_XSS($_GET['selectcat']) . '&selecteval=' . Security::remove_XSS($_GET['selecteval']));
+$category = !empty($_GET['selectcat']) ? $_GET['selectcat'] : "";
+$add_result_form = new EvalForm(EvalForm :: TYPE_RESULT_ADD, $evaluation[0], $resultadd, 'add_result_form', null, api_get_self() . '?selectcat=' . Security::remove_XSS($category) . '&selecteval=' . Security::remove_XSS($_GET['selecteval']));
 $table = $add_result_form->toHtml();
 if ($add_result_form->validate()) {
 	$values = $add_result_form->exportValues();

+ 4 - 1
main/gradebook/gradebook_edit_cat.php

@@ -17,7 +17,10 @@ require_once 'lib/fe/catform.class.php';
 api_block_anonymous_users();
 block_students();
 
-$edit_cat = isset($_REQUEST['editcat']) ? $_REQUEST['editcat'] : '';
+$edit_cat = isset($_REQUEST['editcat']) ? intval($_REQUEST['editcat']) : '';
+
+$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/jquery.fcbkcomplete.js" type="text/javascript" language="javascript"></script>';
+$htmlHeadXtra[] = '<link  href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/style.css" rel="stylesheet" type="text/css" />';
 
 $htmlHeadXtra[] = '<script type="text/javascript">
 $(document).ready(function() {

+ 7 - 2
main/gradebook/gradebook_edit_link.php

@@ -7,7 +7,7 @@
 /**
  * Init
  */
-$language_file = array('gradebook','link');
+$language_file = array('gradebook', 'exercice', 'link');
 //$cidReset = true;
 require_once '../inc/global.inc.php';
 require_once 'lib/be.inc.php';
@@ -33,7 +33,12 @@ if ($link->is_locked() && !api_is_platform_admin()) {
 $linkcat  = isset($_GET['selectcat']) ? Security::remove_XSS($_GET['selectcat']):'';
 $linkedit = isset($_GET['editlink']) ? Security::remove_XSS($_GET['editlink']):'';
 
-$cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init
+$session_id = api_get_session_id();
+if ($session_id == 0) {
+	$cats = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init
+} else {
+    $cats = Category :: load_session_categories(null, $session_id);
+}
 
 $form = new LinkAddEditForm(LinkAddEditForm :: TYPE_EDIT, $cats, null, $link, 'edit_link_form', api_get_self() . '?selectcat=' . $linkcat. '&editlink=' . $linkedit);
 if ($form->validate()) {

+ 52 - 13
main/gradebook/gradebook_flatview.php

@@ -4,9 +4,6 @@
  * Script
  * @package chamilo.gradebook
  */
-/**
- * Init
- */
 
 $language_file = 'gradebook';
 require_once '../inc/global.inc.php';
@@ -70,7 +67,13 @@ if (isset($_GET['selectcat'])) {
 	$category_id = '';
 }
 
-$simple_search_form = new UserForm(UserForm :: TYPE_SIMPLE_SEARCH, null, 'simple_search_form', null, api_get_self() . '?selectcat=' . $category_id);
+$simple_search_form = new UserForm(
+    UserForm :: TYPE_SIMPLE_SEARCH,
+    null,
+    'simple_search_form',
+    null,
+    api_get_self() . '?selectcat=' . $category_id
+);
 $values = $simple_search_form->exportValues();
 
 $keyword = '';
@@ -95,20 +98,31 @@ if (!empty($keyword)) {
 $offset = isset($_GET['offset']) ? $_GET['offset'] : '0';
 
 //$flatviewtable = new FlatViewTable($cat[0], $users, $alleval, $alllinks, true, $offset, $addparams);
-$flatviewtable = new FlatViewTable($cat[0], $users, $alleval, $alllinks, true, $offset);
+$mainCourseCategory = Category::load(null, null, api_get_course_id(), null, null, api_get_session_id());
+
+$flatviewtable = new FlatViewTable(
+    $cat[0],
+    $users,
+    $alleval,
+    $alllinks,
+    true,
+    $offset,
+    $addparams,
+    $mainCourseCategory[0]
+);
 
 $parameters=array('selectcat'=>intval($_GET['selectcat']));
 $flatviewtable->set_additional_parameters($parameters);
 
+$params = array();
 if (isset($_GET['export_pdf']) && $_GET['export_pdf'] == 'category') {
-    $params = array();
     $params['only_total_category'] = true;
     $params['join_firstname_lastname'] = true;
     $params['show_official_code'] = true;
     $params['export_pdf'] = true;
     if ($cat[0]->is_locked() == true || api_is_platform_admin()) {
         Display :: set_header(null, false, false);
-        export_pdf_flatview($cat, $users, $alleval, $alllinks, $params);
+        export_pdf_flatview($flatviewtable, $cat, $users, $alleval, $alllinks, $params, $mainCourseCategory[0]);
     }
 }
 
@@ -118,25 +132,43 @@ if (isset($_GET['exportpdf']))	{
 		'name' => get_lang('FlatView')
 	);
 
-    $export_pdf_form = new DataForm(DataForm::TYPE_EXPORT_PDF, 'export_pdf_form', null, api_get_self().'?exportpdf=&offset='.intval($_GET['offset']).'&selectcat='.intval($_GET['selectcat']), '_blank', '');
+    $export_pdf_form = new DataForm(
+        DataForm::TYPE_EXPORT_PDF,
+        'export_pdf_form',
+        null,
+        api_get_self() . '?exportpdf=&offset=' . intval($_GET['offset']) . '&selectcat=' . intval($_GET['selectcat']),
+        '_blank',
+        ''
+    );
 
 	if ($export_pdf_form->validate()) {
-        $params = array();
         $params = $export_pdf_form->exportValues();
         Display :: set_header(null, false, false);
         $params['join_firstname_lastname'] = true;
         $params['show_official_code'] = true;
         $params['export_pdf'] = true;
         $params['only_total_category'] = false;
-		export_pdf_flatview($cat, $users, $alleval, $alllinks, $params);
+		export_pdf_flatview($flatviewtable, $cat, $users, $alleval, $alllinks, $params, $mainCourseCategory[0]);
 	} else {
 		Display :: display_header(get_lang('ExportPDF'));
 	}
 }
 
 if (isset ($_GET['print']))	{
-	$printable_data = get_printable_data($cat[0], $users, $alleval, $alllinks);
-	echo print_table($printable_data[1],$printable_data[0], get_lang('FlatView'), $cat[0]->get_name());
+    $printable_data = get_printable_data(
+        $cat[0],
+        $users,
+        $alleval,
+        $alllinks,
+        $params,
+        $mainCourseCategory[0]
+    );
+	echo print_table(
+        $printable_data[1],
+        $printable_data[0],
+        get_lang('FlatView'),
+        $cat[0]->get_name()
+    );
 	exit;
 }
 
@@ -152,7 +184,14 @@ if (!empty($_GET['export_report']) && $_GET['export_report'] == 'export_report')
 		}
 
 		require_once 'gradebook_result.class.php';
-		$printable_data = get_printable_data($cat[0], $users, $alleval, $alllinks);
+        $printable_data = get_printable_data(
+            $cat[0],
+            $users,
+            $alleval,
+            $alllinks,
+            $params,
+            $mainCourseCategory[0]
+        );
 
 		switch($_GET['export_format']) {
 			case 'xls':

+ 4 - 15
main/gradebook/gradebook_view_result.php

@@ -68,8 +68,7 @@ if (isset ($_GET['editres'])) {
     $edit_res_xml = Security::remove_XSS($_GET['editres']);
     $select_eval_edit = Security::remove_XSS($_GET['selecteval']);
     $resultedit = Result :: load($edit_res_xml);
-    $edit_res_form = new EvalForm(EvalForm :: TYPE_RESULT_EDIT, $eval[0], $resultedit[0], 'edit_result_form', null, api_get_self(
-    ).'?editres='.$resultedit[0]->get_id().'&selecteval='.$select_eval_edit);
+    $edit_res_form = new EvalForm(EvalForm :: TYPE_RESULT_EDIT, $eval[0], $resultedit[0], 'edit_result_form', null, api_get_self() . '?editres=' . $resultedit[0]->get_id() . '&selecteval=' . $select_eval_edit);
     if ($edit_res_form->validate()) {
 
         $values = $edit_res_form->exportValues();
@@ -92,14 +91,8 @@ if (isset ($_GET['editres'])) {
 
 if (isset ($_GET['import'])) {
 
-    $interbreadcrumb[] = array(
-        'url' => 'gradebook_view_result.php?selecteval='.Security::remove_XSS(
-            $_GET['selecteval']
-        ),
-        'name' => get_lang('ViewResult')
-    );
-    $import_result_form = new DataForm(DataForm :: TYPE_IMPORT, 'import_result_form', null, api_get_self(
-    ).'?import=&selecteval='.Security::remove_XSS($_GET['selecteval']), '_blank', '');
+    $interbreadcrumb[] = array('url' => 'gradebook_view_result.php?selecteval=' . Security::remove_XSS($_GET['selecteval']), 'name' => get_lang('ViewResult'));
+    $import_result_form = new DataForm(DataForm :: TYPE_IMPORT, 'import_result_form', null, api_get_self() . '?import=&selecteval=' . Security::remove_XSS($_GET['selecteval']), '_blank', '');
     if (!$import_result_form->validate()) {
         Display :: display_header(get_lang('Import'));
     }
@@ -126,11 +119,7 @@ if (isset ($_GET['import'])) {
                     if (($importedresult['user_id'] == $allresult->get_user_id())) {
                         if ($importedresult['score'] != $allresult->get_score()) {
                             if (!isset ($values['overwrite'])) {
-                                header(
-                                    'Location: gradebook_view_result.php?selecteval='.Security::remove_XSS(
-                                        $_GET['selecteval']
-                                    ).'&import_score_error='.$importedresult['user_id']
-                                );
+                                header('Location: gradebook_view_result.php?selecteval=' . Security::remove_XSS($_GET['selecteval']) . '&import_score_error=' . $importedresult['user_id']);
                                 exit;
                                 break;
                             } else {

+ 24 - 10
main/gradebook/index.php

@@ -7,7 +7,7 @@
 /**
  * Init
  */
-$language_file= 'gradebook';
+$language_file = array('gradebook', 'exercice');
 // $cidReset : This is the main difference with gradebook.php, here we say,
 // basically, that we are inside a course, and many things depend from that
 $cidReset= false;
@@ -300,13 +300,15 @@ if (isset ($_GET['visiblecat'])) {
 if (isset($_GET['deletecat'])) {
 	block_students();
 	$cats = Category :: load($_GET['deletecat']);
-	//delete all categories,subcategories and results
-	if ($cats[0] != null) {
-		if ($cats[0]->get_id() != 0) {
-			 // better don't try to delete the root...
-			 $cats[0]->delete_all();
+    if (isset($cats[0])) {
+		//delete all categories,subcategories and results
+		if ($cats[0] != null) {
+			if ($cats[0]->get_id() != 0) {
+				 // better don't try to delete the root...
+				 $cats[0]->delete_all();
+			}
 		}
-	}
+    }
 	$confirmation_message = get_lang('CategoryDeleted');
 	$filter_confirm_msg = false;
 }
@@ -813,6 +815,7 @@ if (isset($first_time) && $first_time==1 && api_is_allowed_to_edit(null,true)) {
         }
 
 		$i = 0;
+        $allcat = array();
 
 		foreach ($cats as $cat) {
 			$allcat  = $cat->get_subcategories($stud_id, $course_code, $session_id);
@@ -824,9 +827,20 @@ if (isset($first_time) && $first_time==1 && api_is_allowed_to_edit(null,true)) {
 			} else {
 				//This is the father
 				//Create gradebook/add gradebook links
-                DisplayGradebook::display_header_gradebook($cat, 0, $cat->get_id(), $is_course_admin, $is_platform_admin, $simple_search_form, false, true);
-
-				if (api_is_allowed_to_edit(null,true) && api_get_setting('gradebook_enable_grade_model') == 'true') {
+                DisplayGradebook::display_header_gradebook(
+                    $cat,
+                    0,
+                    $cat->get_id(),
+                    $is_course_admin,
+                    $is_platform_admin,
+                    $simple_search_form,
+                    false,
+                    true
+                );
+
+				if (api_is_allowed_to_edit(null,true) &&
+                    api_get_setting('gradebook_enable_grade_model') == 'true'
+                ) {
 					//Showing the grading system
 					if (!empty($grade_models[$grade_model_id])) {
                         Display::display_normal_message(get_lang('GradeModel').': '.$grade_models[$grade_model_id]['name']);

+ 420 - 358
main/gradebook/lib/be/abstractlink.class.php

@@ -1,6 +1,8 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
+ * Class AbstractLink
  * Defines a gradebook AbstractLink object.
  * To implement specific links,
  * extend this class and define a type in LinkFactory.
@@ -8,435 +10,495 @@
  * @author Bert Steppé
  * @author Julio Montoya <gugli100@gmail.com> security improvements
  * @package chamilo.gradebook
- */
-/**
- * Class
  * @package chamilo.gradebook
  */
-abstract class AbstractLink implements GradebookItem {
-	// PROPERTIES
+abstract class AbstractLink implements GradebookItem
+{
+    protected $id;
+    protected $type;
+    protected $ref_id;
+    protected $user_id;
+    protected $course_code;
+    protected $category;
+    protected $created_at;
+    protected $weight;
+    protected $visible;
+    protected $session_id;
+    public $course_id;
+
+    public function __construct()
+    {
+        $this->course_id = api_get_course_int_id();
+    }
 
-	protected $id;
-	protected $type;
-	protected $ref_id;
-	protected $user_id;
-	protected $course_code;
-	protected $category;
-	protected $created_at;
-	protected $weight;
-	protected $visible;
-	protected $session_id;
-	public    $course_id;
+    public function get_id()
+    {
+        return $this->id;
+    }
 
-	// CONSTRUCTORS
+    public function get_type()
+    {
+        return $this->type;
+    }
 
-    function __construct() {
-    	$this->course_id = api_get_course_int_id();
+    public function get_ref_id()
+    {
+        return $this->ref_id;
     }
 
-	// GETTERS AND SETTERS
+    public function get_session_id()
+    {
+        return $this->session_id;
+    }
 
-   	public function get_id() {
-		return $this->id;
-	}
+    public function get_user_id()
+    {
+        return $this->user_id;
+    }
 
-	public function get_type() {
-		return $this->type;
-	}
+    public function get_course_code()
+    {
+        return $this->course_code;
+    }
 
-	public function get_ref_id() {
-		return $this->ref_id;
-	}
+    public function get_category_id()
+    {
+        return $this->category;
+    }
 
-    public function get_session_id() {
-		return $this->session_id;
-	}
+    public function get_date()
+    {
+        return $this->created_at;
+    }
 
-	public function get_user_id() {
-		return $this->user_id;
-	}
+    public function get_weight()
+    {
+        return $this->weight;
+    }
 
-	public function get_course_code() {
-		return $this->course_code;
-	}
+    public function is_locked()
+    {
+        return isset($this->locked) && $this->locked == 1 ? true : false ;
+    }
 
-	public function get_category_id() {
-		return $this->category;
-	}
+    public function is_visible()
+    {
+        return $this->visible;
+    }
 
-	public function get_date() {
-		return $this->created_at;
-	}
+    public function set_id ($id)
+    {
+        $this->id = $id;
+    }
 
-	public function get_weight() {
-		return $this->weight;
-	}
+    public function set_type ($type)
+    {
+        $this->type = $type;
+    }
 
-    public function is_locked() {
-		return isset($this->locked) && $this->locked == 1 ? true : false ;
-	}
+    public function set_ref_id ($ref_id)
+    {
+        $this->ref_id = $ref_id;
+    }
 
-	public function is_visible() {
-		return $this->visible;
-	}
+    public function set_user_id ($user_id)
+    {
+        $this->user_id = $user_id;
+    }
 
-	public function set_id ($id) {
-		$this->id = $id;
-	}
+    public function set_course_code ($course_code)
+    {
+        $this->course_code = $course_code;
+        $course_info = api_get_course_info($course_code);
+        $this->course_id = $course_info['real_id'];
+    }
 
-	public function set_type ($type) {
-		$this->type = $type;
-	}
+    public function set_category_id ($category_id)
+    {
+        $this->category = $category_id;
+    }
 
-	public function set_ref_id ($ref_id) {
-		$this->ref_id = $ref_id;
-	}
+    public function set_date ($date)
+    {
+        $this->created_at = $date;
+    }
 
-	public function set_user_id ($user_id) {
-		$this->user_id = $user_id;
-	}
+    public function set_weight ($weight)
+    {
+        $this->weight = $weight;
+    }
 
-	public function set_course_code ($course_code) {
-		$this->course_code = $course_code;
-        $course_info = api_get_course_info($course_code);
-        $this->course_id = $course_info['real_id'];
-	}
-
-	public function set_category_id ($category_id) {
-		$this->category = $category_id;
-	}
-
-	public function set_date ($date) {
-		$this->created_at = $date;
-	}
-
-	public function set_weight ($weight) {
-		$this->weight = $weight;
-	}
-
-	public function set_visible ($visible) {
-		$this->visible = $visible;
-	}
-
-    public function set_session_id($id) {
-    	$this->session_id = $id;
-    }
-    public function set_locked ($locked) {
-		$this->locked = $locked;
-	}
-
-    // CRUD FUNCTIONS
-
-	/**
-	 * Retrieve links and return them as an array of extensions of AbstractLink.
-	 * To keep consistency, do not call this method but LinkFactory::load instead.
-	 */
-	public static function load ($id = null, $type = null, $ref_id = null, $user_id = null, $course_code = null, $category_id = null, $visible = null) {
-    	$tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-		$sql='SELECT * FROM '.$tbl_grade_links;
-		$paramcount = 0;
-		if (isset ($id)) {
-			$sql.= ' WHERE id = '.Database::escape_string($id);
-			$paramcount ++;
-		}
-		if (isset ($type)) {
-			if ($paramcount != 0) $sql .= ' AND';
-			else $sql .= ' WHERE';
-			$sql .= ' type = '.Database::escape_string($type);
-			$paramcount ++;
-		}
-		if (isset ($ref_id)) {
-			if ($paramcount != 0) $sql .= ' AND';
-			else $sql .= ' WHERE';
-			$sql .= ' ref_id = '.intval($ref_id);
-			$paramcount ++;
-		}
-		if (isset ($user_id)) {
-			if ($paramcount != 0) {
-			$sql .= ' AND';
-			}else {
-			 $sql .= ' WHERE';
-			}
-			$sql .= ' user_id = '.intval($user_id);
-			$paramcount ++;
-		}
-		if (isset ($course_code)) {
-			if ($paramcount != 0) {
-			 $sql .= ' AND';
-			} else {
-			 $sql .= ' WHERE';
-			}
-			$sql .= " course_code = '".Database::escape_string($course_code)."'";
-			$paramcount ++;
-		}
-		if (isset ($category_id)) {
-			if ($paramcount != 0) {
-				$sql .= ' AND';
-			}else {
-			 	$sql .= ' WHERE';
-			}
-			$sql .= ' category_id = '.intval($category_id);
-			$paramcount ++;
-		}
-		if (isset ($visible)) {
-			if ($paramcount != 0) {
-				$sql .= ' AND';
-			} else {
-				 $sql .= ' WHERE';
-			}
-			$sql .= ' visible = '.intval($visible);
-			$paramcount ++;
-		}
-
-		$result = Database::query($sql);
-		$links = AbstractLink::create_objects_from_sql_result($result);
-		return $links;
-	}
-
-    private static function create_objects_from_sql_result($result) {
-    	$links=array();
-		while ($data=Database::fetch_array($result)) {
-			$link = LinkFactory::create($data['type']);
-			$link->set_id($data['id']);
-			$link->set_type($data['type']);
-			$link->set_ref_id($data['ref_id']);
-			$link->set_user_id($data['user_id']);
-			$link->set_course_code($data['course_code']);
-			$link->set_category_id($data['category_id']);
-			$link->set_date($data['created_at']);
-			$link->set_weight($data['weight']);
-			$link->set_visible($data['visible']);
+    public function set_visible ($visible)
+    {
+        $this->visible = $visible;
+    }
+
+    public function set_session_id($id)
+    {
+        $this->session_id = $id;
+    }
+
+    /**
+     * @param $locked
+     */
+    public function set_locked($locked)
+    {
+        $this->locked = $locked;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCourseId()
+    {
+        return $this->course_id;
+    }
+
+    /**
+     * Retrieve links and return them as an array of extensions of AbstractLink.
+     * To keep consistency, do not call this method but LinkFactory::load instead.
+     */
+    public static function load(
+        $id = null,
+        $type = null,
+        $ref_id = null,
+        $user_id = null,
+        $course_code = null,
+        $category_id = null,
+        $visible = null
+    )
+    {
+        $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
+        $sql = 'SELECT * FROM '.$tbl_grade_links;
+        $paramcount = 0;
+        if (isset ($id)) {
+            $sql.= ' WHERE id = '.Database::escape_string($id);
+            $paramcount ++;
+        }
+        if (isset ($type)) {
+            if ($paramcount != 0) $sql .= ' AND';
+            else $sql .= ' WHERE';
+            $sql .= ' type = '.Database::escape_string($type);
+            $paramcount ++;
+        }
+        if (isset ($ref_id)) {
+            if ($paramcount != 0) $sql .= ' AND';
+            else $sql .= ' WHERE';
+            $sql .= ' ref_id = '.intval($ref_id);
+            $paramcount ++;
+        }
+        if (isset ($user_id)) {
+            if ($paramcount != 0) {
+                $sql .= ' AND';
+            }else {
+                $sql .= ' WHERE';
+            }
+            $sql .= ' user_id = '.intval($user_id);
+            $paramcount ++;
+        }
+        if (isset ($course_code)) {
+            if ($paramcount != 0) {
+             $sql .= ' AND';
+            } else {
+             $sql .= ' WHERE';
+            }
+            $sql .= " course_code = '".Database::escape_string($course_code)."'";
+            $paramcount ++;
+        }
+        if (isset ($category_id)) {
+            if ($paramcount != 0) {
+                $sql .= ' AND';
+            }else {
+                $sql .= ' WHERE';
+            }
+            $sql .= ' category_id = '.intval($category_id);
+            $paramcount ++;
+        }
+        if (isset ($visible)) {
+            if ($paramcount != 0) {
+                $sql .= ' AND';
+            } else {
+                 $sql .= ' WHERE';
+            }
+            $sql .= ' visible = '.intval($visible);
+        }
+
+        $result = Database::query($sql);
+        $links = AbstractLink::create_objects_from_sql_result($result);
+        return $links;
+    }
+
+    /**
+     * @param $result
+     * @return array
+     */
+    private static function create_objects_from_sql_result($result)
+    {
+        $links = array();
+        while ($data = Database::fetch_array($result)) {
+            $link = LinkFactory::create($data['type']);
+            $link->set_id($data['id']);
+            $link->set_type($data['type']);
+            $link->set_ref_id($data['ref_id']);
+            $link->set_user_id($data['user_id']);
+            $link->set_course_code($data['course_code']);
+            $link->set_category_id($data['category_id']);
+            $link->set_date($data['created_at']);
+            $link->set_weight($data['weight']);
+            $link->set_visible($data['visible']);
             $link->set_locked($data['locked']);
 
             //session id should depend of the category --> $data['category_id']
             $session_id = api_get_session_id();
 
             $link->set_session_id($session_id);
-			$links[]=$link;
-		}
-		return $links;
+            $links[]=$link;
+        }
+        return $links;
     }
 
-
     /**
      * Insert this link into the database
      */
-    public function add() {
-		$this->add_linked_data();
-		if (isset($this->type) && isset($this->ref_id) && isset($this->user_id) && isset($this->course_code) && isset($this->category) && isset($this->weight) && isset($this->visible)) {
-			$tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-			$sql_testing="SELECT count(*) FROM ".$tbl_grade_links." WHERE ref_id=".$this->get_ref_id()." AND category_id =  ".$this->category." AND type =  ".$this->type." ;";
-			$result_testing=Database::query($sql_testing);
-			$row_testing=Database::fetch_array($result_testing);
-
-			if ($row_testing[0]==0) {
-				$sql = 'INSERT INTO '.$tbl_grade_links.' (type, ref_id, user_id, course_code, category_id, weight, visible, created_at';
-				$sql .= ') VALUES ('
-					.intval($this->get_type())
-					.','.intval($this->get_ref_id())
-					.','.intval($this->get_user_id())
-					.",'".Database::escape_string($this->get_course_code())."'"
-					.','.intval($this->get_category_id())
-					.",'".Database::escape_string($this->get_weight())."'"
-					.','.intval($this->is_visible());
-				$sql .= ','.'"'.$date_current=api_get_local_time().'"';
-				$sql .= ")";
-				Database::query($sql);
+    public function add()
+    {
+        $this->add_linked_data();
+        if (isset($this->type) && isset($this->ref_id) && isset($this->user_id) && isset($this->course_code) && isset($this->category) && isset($this->weight) && isset($this->visible)) {
+            $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
+            $sql = "SELECT count(*) FROM ".$tbl_grade_links."
+                    WHERE
+                        ref_id=".$this->get_ref_id()." AND
+                        category_id =  ".$this->category." AND
+                        course_code = '".$this->course_code."' AND
+                        type =  ".$this->type." ";
+
+            $result = Database::query($sql);
+            $row_testing = Database::fetch_array($result);
+
+            if ($row_testing[0]==0) {
+                $sql = 'INSERT INTO '.$tbl_grade_links.' (type, ref_id, user_id, course_code, category_id, weight, visible, created_at) VALUES ('
+                    .intval($this->get_type())
+                    .','.intval($this->get_ref_id())
+                    .','.intval($this->get_user_id())
+                    .",'".Database::escape_string($this->get_course_code())."'"
+                    .','.intval($this->get_category_id())
+                    .",'".Database::escape_string($this->get_weight())."'"
+                    .','.intval($this->is_visible());
+                $sql .= ','.'"'.$date_current = api_get_local_time().'"';
+                $sql .= ")";
+                Database::query($sql);
                 $inserted_id = Database::insert_id();
-				$this->set_id($inserted_id);
+                $this->set_id($inserted_id);
                 return $inserted_id;
-		 	}
-		} else {
-			die('Error in AbstractLink add: required field empty');
-		}
+            }
+        } else {
+            die('Error in AbstractLink add: required field empty');
+        }
         return false;
-	}
+    }
 
-	/**
-	 * Update the properties of this link in the database
-	 */
-	public function save() {
-		$this->save_linked_data();
+    /**
+     * Update the properties of this link in the database
+     */
+    public function save() {
+        $this->save_linked_data();
 
-		$tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-		$sql = "UPDATE $tbl_grade_links SET
+        $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
+        $sql = "UPDATE $tbl_grade_links SET
                     type        = ".intval($this->get_type()).",
-				    ref_id      = ".intval($this->get_ref_id()).",
-				    user_id     = ".intval($this->get_user_id()).",
-				    course_code = '".Database::escape_string($this->get_course_code())."',
-				    category_id = ".intval($this->get_category_id()).",
-		            weight      = '".Database::escape_string($this->get_weight())."',
-				    visible     = ".intval($this->is_visible())."
-			     WHERE id = ".intval($this->id);
-
-		AbstractLink::add_link_log($this->id);
-
-		Database::query($sql);
-	}
-
-	public function add_link_log($idevaluation) {
-		$tbl_grade_linkeval_log = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
-		$dateobject=AbstractLink::load ($idevaluation,null,null,null,null);
-		$current_date_server=api_get_utc_datetime();
-		$arreval=get_object_vars($dateobject[0]);
-		$description_log=isset($arreval['description'])?$arreval['description']:'';
-		if (isset($_POST['name_link'])) {
-			$name_log=isset($_POST['name_link'])?Security::remove_XSS($_POST['name_link']):$arreval['course_code'];
-		} elseif ($_POST['link_'.$idevaluation]) {
-			$name_log=$_POST['link_'.$idevaluation];
-		} else {
-			$name_log=$arreval['course_code'];
-		}
-		$sql="INSERT INTO ".$tbl_grade_linkeval_log."(id_linkeval_log,name,description,created_at,weight,visible,type,user_id_log)
-			  VALUES('".Database::escape_string($arreval['id'])."','".Database::escape_string($name_log)."','".Database::escape_string($description_log)."','".Database::escape_string($current_date_server)."','".Database::escape_string($arreval['weight'])."','".Database::escape_string($arreval['visible'])."','Link',".api_get_user_id().")";
-
-		Database::query($sql);
-
-	}
-	/**
-	 * Delete this link from the database
-	 */
-	public function delete() {
-		$this->delete_linked_data();
-		$tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-		$sql = 'DELETE FROM '.$tbl_grade_links.' WHERE id = '.intval($this->id);
-		Database::query($sql);
-	}
-
-
-// OTHER FUNCTIONS
-
-	/**
-	 * Generate an array of possible categories where this link can be moved to.
-	 * Notice: its own parent will be included in the list: it's up to the frontend
-	 * to disable this element.
-	 * @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
-	 */
-    public function get_target_categories() {
-    	// links can only be moved to categories inside this course
-
-		$targets = array();
-		$level = 0;
-
-		$crscats = Category::load(null,null,$this->get_course_code(),0);
-		foreach ($crscats as $cat) {
-			$targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
-			$targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
-		}
-
-		return $targets;
+                    ref_id      = ".intval($this->get_ref_id()).",
+                    user_id     = ".intval($this->get_user_id()).",
+                    course_code = '".Database::escape_string($this->get_course_code())."',
+                    category_id = ".intval($this->get_category_id()).",
+                    weight      = '".Database::escape_string($this->get_weight())."',
+                    visible     = ".intval($this->is_visible())."
+                 WHERE id = ".intval($this->id);
+
+        AbstractLink::add_link_log($this->id);
+
+        Database::query($sql);
+    }
+
+    /**
+     * @param int $idevaluation
+     */
+    public function add_link_log($idevaluation)
+    {
+        $tbl_grade_linkeval_log = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
+        $dateobject=AbstractLink::load ($idevaluation,null,null,null,null);
+        $current_date_server=api_get_utc_datetime();
+        $arreval=get_object_vars($dateobject[0]);
+        $description_log=isset($arreval['description'])?$arreval['description']:'';
+        if (isset($_POST['name_link'])) {
+            $name_log=isset($_POST['name_link'])?Security::remove_XSS($_POST['name_link']):$arreval['course_code'];
+        } elseif ($_POST['link_'.$idevaluation]) {
+            $name_log=$_POST['link_'.$idevaluation];
+        } else {
+            $name_log=$arreval['course_code'];
+        }
+        $sql="INSERT INTO ".$tbl_grade_linkeval_log."(id_linkeval_log,name,description,created_at,weight,visible,type,user_id_log)
+              VALUES('".Database::escape_string($arreval['id'])."','".Database::escape_string($name_log)."','".Database::escape_string($description_log)."','".Database::escape_string($current_date_server)."','".Database::escape_string($arreval['weight'])."','".Database::escape_string($arreval['visible'])."','Link',".api_get_user_id().")";
+
+        Database::query($sql);
+    }
+
+    /**
+     * Delete this link from the database
+     */
+    public function delete() {
+        $this->delete_linked_data();
+        $tbl_grade_links = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
+        $sql = 'DELETE FROM '.$tbl_grade_links.' WHERE id = '.intval($this->id);
+        Database::query($sql);
     }
 
     /**
-	 * Internal function used by get_target_categories()
-	 */
-	private function add_target_subcategories($targets, $level, $catid) {
-		$subcats = Category::load(null,null,null,$catid);
-		foreach ($subcats as $cat) {
-			$targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
-			$targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
-		}
-		return $targets;
-	}
+     * Generate an array of possible categories where this link can be moved to.
+     * Notice: its own parent will be included in the list: it's up to the frontend
+     * to disable this element.
+     * @return array 2-dimensional array - every element contains 3 subelements (id, name, level)
+     */
+    public function get_target_categories()
+    {
+        // links can only be moved to categories inside this course
+
+        $targets = array();
+        $level = 0;
+
+        $crscats = Category::load(null,null,$this->get_course_code(),0);
+        foreach ($crscats as $cat) {
+            $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
+            $targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
+        }
+
+        return $targets;
+    }
 
     /**
-	 * Move this link to the given category.
-	 * If this link moves to outside a course, delete it.
-	 */
-    public function move_to_cat($cat) {
-		if ($this->get_course_code() != $cat->get_course_code()) {
-			$this->delete();
-		} else {
-			$this->set_category_id($cat->get_id());
-			$this->save();
-		}
+     * Internal function used by get_target_categories()
+     */
+    private function add_target_subcategories($targets, $level, $catid)
+    {
+        $subcats = Category::load(null,null,null,$catid);
+        foreach ($subcats as $cat) {
+            $targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
+            $targets = $this->add_target_subcategories($targets, $level+1, $cat->get_id());
+        }
+        return $targets;
     }
 
+    /**
+     * Move this link to the given category.
+     * If this link moves to outside a course, delete it.
+     */
+    public function move_to_cat($cat)
+    {
+        if ($this->get_course_code() != $cat->get_course_code()) {
+            $this->delete();
+        } else {
+            $this->set_category_id($cat->get_id());
+            $this->save();
+        }
+    }
 
     /**
      * Find links by name
-	 * To keep consistency, do not call this method but LinkFactory::find_links instead.
+     * To keep consistency, do not call this method but LinkFactory::find_links instead.
      * @todo can be written more efficiently using a new (but very complex) sql query
      */
-    public function find_links ($name_mask,$selectcat) {
-    	$rootcat = Category::load($selectcat);
-		$links = $rootcat[0]->get_links((api_is_allowed_to_edit() ? null : api_get_user_id()), true);
-		$foundlinks = array();
-		foreach ($links as $link) {
-			if (!(api_strpos(api_strtolower($link->get_name()), api_strtolower($name_mask)) === false)) {
-				$foundlinks[] = $link;
-			}
-		}
-		return $foundlinks;
+    public function find_links ($name_mask,$selectcat)
+    {
+        $rootcat = Category::load($selectcat);
+        $links = $rootcat[0]->get_links((api_is_allowed_to_edit() ? null : api_get_user_id()), true);
+        $foundlinks = array();
+        foreach ($links as $link) {
+            if (!(api_strpos(api_strtolower($link->get_name()), api_strtolower($name_mask)) === false)) {
+                $foundlinks[] = $link;
+            }
+        }
+        return $foundlinks;
     }
 
 
-// Other methods implementing GradebookItem
+    // Other methods implementing GradebookItem
+    public function get_item_type()
+    {
+        return 'L';
+    }
 
-	public function get_item_type() {
-		return 'L';
-	}
+    public function get_icon_name() {
+        return 'link';
+    }
 
-	public function get_icon_name() {
-		return 'link';
-	}
-// ABSTRACT FUNCTIONS - to be implemented by subclass
+    // ABSTRACT FUNCTIONS - to be implemented by subclass
 
     abstract function has_results();
-	abstract function get_link();
-	abstract function is_valid_link();
-	abstract function get_type_name();
+    abstract function get_link();
+    abstract function is_valid_link();
+    abstract function get_type_name();
 
-	// The following methods are already defined in GradebookItem,
-	// and must be implemented by the subclass as well !
-//	abstract function get_name();
-//	abstract function get_description();
-//  abstract function calc_score($stud_id = null);
+    // The following methods are already defined in GradebookItem,
+    // and must be implemented by the subclass as well !
+    //	abstract function get_name();
+    //	abstract function get_description();
+    //  abstract function calc_score($stud_id = null);
 
-	abstract function needs_name_and_description();
-	abstract function needs_max();
-	abstract function needs_results();
-	abstract function is_allowed_to_change_name();
+    abstract function needs_name_and_description();
+    abstract function needs_max();
+    abstract function needs_results();
+    abstract function is_allowed_to_change_name();
 
     /* TRIVIAL FUNCTIONS - to be overwritten by subclass if needed */
 
     /* Seems to be not used anywhere */
-	public function get_not_created_links() {
-		return null;
-	}
-	public function get_all_links() {
-		return null;
-	}
+    public function get_not_created_links()
+    {
+        return null;
+    }
+
+    public function get_all_links()
+    {
+        return null;
+    }
 
-	public function add_linked_data() {
-	}
+    public function add_linked_data()
+    {
+    }
 
-	public function save_linked_data() {
-	}
+    public function save_linked_data()
+    {
+    }
+
+    public function delete_linked_data()
+    {
+    }
 
-	public function delete_linked_data() {
-	}
+    public function set_name ($name)
+    {
+    }
 
-	public function set_name ($name) {
-	}
+    public function set_description ($description)
+    {
+    }
 
-	public function set_description ($description) {
-	}
+    public function set_max ($max)
+    {
+    }
 
-	public function set_max ($max) {
-	}
-	public function get_view_url ($stud_id) {
-		return null;
-	}
+    public function get_view_url ($stud_id)
+    {
+        return null;
+    }
 
     /**
-  	 * Locks a link
-  	 * @param int locked 1 or unlocked 0
-  	 *
-  	 * */
-  	function lock($locked) {
-  		$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-  		$sql = "UPDATE $table SET locked = '".intval($locked)."' WHERE id='".$this->id."'";
-  		Database::query($sql);
-  	}
+     * Locks a link
+     * @param int locked 1 or unlocked 0
+     *
+     * */
+    function lock($locked)
+    {
+        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
+        $sql = "UPDATE $table SET locked = '".intval($locked)."' WHERE id='".$this->id."'";
+        Database::query($sql);
+    }
 }

+ 159 - 75
main/gradebook/lib/be/category.class.php

@@ -1,16 +1,10 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
+ * Class Category
  * Defines a gradebook Category object
  * @package chamilo.gradebook
  */
-/**
- * Init
- */
-/**
- * Class
- * @package chamilo.gradebook
- */
 
 
 class Category implements GradebookItem
@@ -202,7 +196,43 @@ class Category implements GradebookItem
         return $skill_select;
     }
 
-    // CRUD FUNCTIONS
+    /**
+     * @param int $id
+     * @param int $session_id
+     *
+     * @return array
+     */
+    public static function load_session_categories($id = null, $session_id = null)
+    {
+        if (isset($id) && (int)$id === 0) {
+            $cats = array();
+            $cats[] = Category::create_root_category();
+            return $cats;
+        }
+    	// CRUD FUNCTIONS
+        $courseCode = api_get_course_info(api_get_course_id());
+        $courseCode = $courseCode['code'];
+        $session_id = intval($session_id);
+
+        if (!empty($session_id)) {
+             $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
+             $sql = 'SELECT id, course_code FROM '.$tbl_grade_categories. '
+                     WHERE session_id = '.$session_id;
+             $result_session = Database::query($sql);
+             if (Database::num_rows($result_session) > 0) {
+                $categoryList = array();
+                while ($data_session = Database::fetch_array($result_session)) {
+                    $parent_id = $data_session['id'];
+                    if ($data_session['course_code'] == $courseCode) {
+                        $categories = Category::load($parent_id);
+                        $categoryList = array_merge($categoryList, $categories);
+                        //$allSubCategories = Category::load(null,null,null, $parent_id, null, $session_id, null);
+                    }
+                }
+                return $categoryList;
+             }
+        }
+    }
 
     /**
      * Retrieve categories and return them as an array of Category objects
@@ -301,7 +331,6 @@ class Category implements GradebookItem
                 $sql .= ' WHERE';
             }
             $sql .= ' visible = '.intval($visible);
-            $paramcount++;
         }
 
         if (!empty($order_by)) {
@@ -547,7 +576,11 @@ class Category implements GradebookItem
 
 
         $gradebook = new Gradebook();
-        $gradebook->update_skills_to_gradebook($this->id, $this->get_skills(false));
+        $gradebook->update_skills_to_gradebook(
+            $this->id,
+            $this->get_skills(false),
+            false
+        );
 
     }
 
@@ -590,9 +623,7 @@ class Category implements GradebookItem
     public function update_category_delete($course_id)
     {
         $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
-        $sql                  = 'UPDATE '.$tbl_grade_categories.' SET visible=3 WHERE course_code ="'.Database::escape_string(
-                $course_id
-            ).'"';
+        $sql = 'UPDATE '.$tbl_grade_categories.' SET visible=3 WHERE course_code ="'.Database::escape_string($course_id).'"';
         Database::query($sql);
     }
 
@@ -602,9 +633,10 @@ class Category implements GradebookItem
     public function show_message_resource_delete($course_id)
     {
         $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
-        $sql                  = 'SELECT count(*) AS num from '.$tbl_grade_categories.' WHERE course_code ="'.Database::escape_string(
-                $course_id
-            ).'" AND visible=3';
+        $sql = 'SELECT count(*) AS num from '.$tbl_grade_categories.'
+                WHERE
+                    course_code = "'.Database::escape_string($course_id).'" AND
+                    visible=3';
         $res                  = Database::query($sql);
         $option               = Database::fetch_array($res, 'ASSOC');
         if ($option['num'] >= 1) {
@@ -623,9 +655,7 @@ class Category implements GradebookItem
             return null;
         } else {
             $tbl_category = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
-            $sql          = 'SELECT name,description,user_id,course_code,parent_id,weight,visible,certif_min_score,session_id
-                    FROM '.$tbl_category.' c
-                    WHERE c.id = '.intval($selectcat);
+             $sql='SELECT name,description,user_id,course_code,parent_id,weight,visible,certif_min_score,session_id FROM '.$tbl_category.' c WHERE c.id='.intval($selectcat);
             $result       = Database::query($sql);
             $row          = Database::fetch_array($result, 'ASSOC');
 
@@ -751,11 +781,15 @@ class Category implements GradebookItem
                 $evalres = $eval->calc_score($stud_id);
                 if (isset($evalres) && $eval->get_weight() != 0) {
                     $evalweight = $eval->get_weight();
-                    $rescount++;
                     $weightsum += $evalweight;
+                    $rescount++;
                     $ressum += (($evalres[0] / $evalres[1]) * $evalweight);
                 } else {
 
+                    if ($eval->get_weight() != 0) {
+                        $evalweight = $eval->get_weight();
+                        $weightsum += $evalweight;
+                    }
                 }
             }
         }
@@ -826,10 +860,11 @@ class Category implements GradebookItem
         // courses
 
         $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
-        $course_table           = Database :: get_main_table(TABLE_MAIN_COURSE);
         $tbl_grade_categories   = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
 
-        $sql = 'SELECT * FROM '.$tbl_grade_categories.' WHERE parent_id = 0';
+        $sql = 'SELECT *'
+                .' FROM '.$tbl_grade_categories
+                .' WHERE parent_id = 0';
         if (!api_is_allowed_to_edit()) {
             $sql .= ' AND visible = 1';
             //proceed with checks on optional parameters course & session
@@ -842,18 +877,15 @@ class Category implements GradebookItem
                     $sql .= " AND course_code  = '".Database::escape_string($course_code)."'"
                         ." AND session_id = ".(int)$session_id;
                 } else {
-                    $sql .= " AND course_code  = '".Database::escape_string(
-                            $course_code
-                        )."' AND session_id is null OR session_id=0";
+                    $sql .= " AND course_code  = '".Database::escape_string($course_code)."' AND session_id is null OR session_id=0";
                 }
             } else {
                 //no optional parameter, proceed as usual
-                $sql .= ' AND course_code IN
-                         (
-                            SELECT course.code
-                            FROM '.$main_course_user_table.' course_user
-                            INNER JOIN '.$course_table.' course ON (course.id AND course_user.c_id)
-                            WHERE user_id = '.intval($stud_id).' AND status = '.STUDENT
+                $sql .= ' AND course_code in'
+                    .' (SELECT course_code'
+                    .' FROM '.$main_course_user_table
+                    .' WHERE user_id = '.intval($stud_id)
+                    .' AND status = '.STUDENT
                     .')';
             }
         } elseif (api_is_allowed_to_edit() && !api_is_platform_admin()) {
@@ -871,7 +903,8 @@ class Category implements GradebookItem
                 }
             } else {
                 $sql .= ' AND course_code in'
-                    .' (SELECT course_code FROM '.$main_course_user_table
+                        .' (SELECT course_code'
+                        .' FROM '.$main_course_user_table
                     .' WHERE user_id = '.api_get_user_id()
                     .' AND status = '.COURSEMANAGER
                     .')';
@@ -910,21 +943,20 @@ class Category implements GradebookItem
         // Courses
         $main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
         $tbl_grade_categories   = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
-        $course_table           = Database :: get_main_table(TABLE_MAIN_COURSE);
 
-        $sql = 'SELECT * FROM '.$tbl_grade_categories.' WHERE parent_id = 0';
+        $sql = 'SELECT *'
+                .' FROM '.$tbl_grade_categories
+                .' WHERE parent_id = 0';
         if (!empty($course_code)) {
             $sql .= " AND course_code = '".Database::escape_string($course_code)."' ";
             if (!empty($session_id)) {
                 $sql .= " AND session_id = ".(int)$session_id;
             }
         } else {
-            $sql .= ' AND course_code IN
-                         (
-                            SELECT course.code
-                            FROM '.$main_course_user_table.' course_user
-                            INNER JOIN '.$course_table.' course ON (course.id AND course_user.c_id)
-                            WHERE user_id = '.intval($stud_id).' AND status = '.STUDENT
+            $sql .= ' AND course_code in'
+                .' (SELECT course_code'
+                .' FROM '.$main_course_user_table
+                .' WHERE user_id = '.intval($user_id)
                 .')';
         }
         $result = Database::query($sql);
@@ -959,12 +991,11 @@ class Category implements GradebookItem
         // the root or a course -> not movable
         if (!$this->is_movable()) {
             return null;
-        } // otherwise:
+        } else {
         // - course independent category
         //   -> movable to root or other independent categories
         // - category inside a course
         //   -> movable to root, independent categories or categories inside the course
-        else {
             $user    = (api_is_platform_admin() ? null : api_get_user_id());
             $targets = array();
             $level   = 0;
@@ -1153,7 +1184,6 @@ class Category implements GradebookItem
     {
         $tbl_main_courses     = Database :: get_main_table(TABLE_MAIN_COURSE);
         $tbl_main_course_user = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
-        $tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
 
         $sql = 'SELECT DISTINCT(code), title FROM '.$tbl_main_courses.' cc, '.$tbl_main_course_user.' cu'
             .' WHERE cc.id = cu.c_id'
@@ -1273,25 +1303,28 @@ class Category implements GradebookItem
      * @param int $stud_id student id (default: all students)
      * @param string   Course code (optional)
      * @param int      Session ID (optional)
+     *
      * @return  array   Array of subcategories
      */
     public function get_subcategories($stud_id = null, $course_code = null, $session_id = null, $order = null)
     {
+        if (!empty($session_id)) {
+             /*$tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
+             $sql = 'SELECT id FROM '.$tbl_grade_categories. ' WHERE session_id = '.$session_id;
+             $result_session = Database::query($sql);
+             if (Database::num_rows($result_session) > 0) {
+                 $data_session = Database::fetch_array($result_session);
+                 $parent_id = $data_session['id'];
+                 return Category::load(null, null, null, $parent_id, null, null, $order);
+             }*/
+         }
         // 1 student
         if (isset($stud_id)) {
             // special case: this is the root
             if ($this->id == 0) {
                 return Category::get_root_categories_for_student($stud_id, $course_code, $session_id);
             } else {
-                return Category::load(
-                    null,
-                    null,
-                    $course_code,
-                    $this->id,
-                    api_is_allowed_to_edit() ? null : 1,
-                    $session_id,
-                    $order
-                );
+                return Category::load(null,null, $course_code, $this->id, api_is_allowed_to_edit() ? null : 1, $session_id, $order);
             }
         } else { // all students
             // course admin
@@ -1322,6 +1355,9 @@ class Category implements GradebookItem
      * Get appropriate evaluations visible for the user
      * @param int $stud_id student id (default: all students)
      * @param boolean $recursive process subcategories (default: no recursion)
+     * @param string $course_code
+     *
+     * @return array
      */
     public function get_evaluations($stud_id = null, $recursive = false, $course_code = '')
     {
@@ -1377,8 +1413,12 @@ class Category implements GradebookItem
      * Get appropriate links visible for the user
      * @param int $stud_id student id (default: all students)
      * @param boolean $recursive process subcategories (default: no recursion)
+     * @param string $course_code
+     * @param int $sessionId
+     *
+     * @return array
      */
-    public function get_links($stud_id = null, $recursive = false, $course_code = '')
+    public function get_links($stud_id = null, $recursive = false, $course_code = '', $sessionId = null)
     {
         $links = array();
 
@@ -1386,6 +1426,10 @@ class Category implements GradebookItem
             $course_code = api_get_course_id();
         }
 
+        if (empty($sessionId)) {
+            $sessionId = api_get_session_id();
+        }
+
         // no links in root or course independent categories
         if ($this->id == 0) {
 
@@ -1415,10 +1459,14 @@ class Category implements GradebookItem
 
 
         if ($recursive) {
-            $subcats = $this->get_subcategories($stud_id, $course_code);
+            $subcats = $this->get_subcategories(
+                $stud_id,
+                $course_code,
+                $sessionId
+            );
             if (!empty($subcats)) {
                 foreach ($subcats as $subcat) {
-                    $sublinks = $subcat->get_links($stud_id, false, $course_code);
+                    $sublinks = $subcat->get_links($stud_id, false, $course_code, $sessionId);
                     $links    = array_merge($links, $sublinks);
                 }
             }
@@ -1428,24 +1476,52 @@ class Category implements GradebookItem
 
     }
 
+    /**
+     * Get all the categories from with the same given direct parent
+     * @param int $catId Category parent ID
+     * @return array Array of Category objects
+     */
+    public function getCategories($catId)
+    {
+        $tblGradeCategories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
+        $courseInfo = api_get_course_info(api_get_course_id());
+        $courseCode = $courseInfo['code'];
+        $sql='SELECT * FROM '.$tblGradeCategories.' WHERE parent_id = '.intval($catId);
 
+        $result = Database::query($sql);
+        $allcats = Category::create_category_objects_from_sql_result($result);
+        return $allcats;
+    }
 // Other methods implementing GradebookItem
 
+    /**
+     * Gets the type for the current object
+     * @return string 'C' to represent "Category" object type
+     */
     public function get_item_type()
     {
         return 'C';
     }
 
+    /**
+     * @param array $skills
+     */
     public function set_skills($skills)
     {
         $this->skills = $skills;
     }
 
+    /**
+     * @return null
+     */
     public function get_date()
     {
         return null;
     }
 
+    /**
+     * @return string
+     */
     public function get_icon_name()
     {
         return 'cat';
@@ -1474,14 +1550,17 @@ class Category implements GradebookItem
      * @return bool
      *
      * */
-    function lock($locked)
+    public function lock($locked)
     {
         $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
         $sql   = "UPDATE $table SET locked = '".intval($locked)."' WHERE id='".intval($this->id)."'";
         Database::query($sql);
     }
 
-    function lock_all_items($locked)
+    /**
+     * @param $locked
+     */
+    public function lock_all_items($locked)
     {
         if (api_get_setting('gradebook_locking_enabled') == 'true') {
             $this->lock($locked);
@@ -1509,17 +1588,21 @@ class Category implements GradebookItem
         }
     }
 
-    static function register_user_certificate($category_id, $user_id)
+    /**
+     * @param int $category_id
+     * @param int $user_id
+     * @return bool|string
+     */
+    public static function register_user_certificate($category_id, $user_id)
     {
         // generating the total score for a course
-        $cats_course = Category :: load($category_id, null, null, null, null, null, false);
+        $cats_course = Category::load($category_id, null, null, null, null, api_get_session_id(), false);
 
         $alleval_course = $cats_course[0]->get_evaluations($user_id, true);
         $alllink_course = $cats_course[0]->get_links($user_id, true);
 
         $evals_links = array_merge($alleval_course, $alllink_course);
 
-        $item_total = 0;
 
         //@todo move these in a function
         $sum_categories_weight_array = array();
@@ -1543,8 +1626,9 @@ class Category implements GradebookItem
             $item               = $evals_links[$count];
             $score              = $item->calc_score($user_id);
             $divide             = (($score[1]) == 0) ? 1 : $score[1];
-            $sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
-            $item_value         = $score[0] / $divide * $item->get_weight() * $sub_cat_percentage / $main_weight;
+            $item_value = $score[0]/$divide*$item->get_weight();
+            /*var_dump($score[0], $divide, $item->get_weight(), $item_value);
+            echo '---';-*/
             $item_total_value += $item_value;
         }
         $item_total_value = (float)$item_total_value;
@@ -1561,37 +1645,37 @@ class Category implements GradebookItem
         //Show certificate
         $certificate_min_score = $cats_course[0]->get_certificate_min_score();
 
-        $scoretotal_display = $scoredisplay->display_score(
-            $scoretotal,
-            SCORE_DIV_PERCENT
-        ); //a student always sees only the teacher's repartition
+        $scoretotal_display = $scoredisplay->display_score($scoretotal, SCORE_DIV_PERCENT);
 
         if (isset($certificate_min_score) && $item_total_value >= $certificate_min_score) {
             $my_certificate = get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
             if (empty($my_certificate)) {
-                register_user_info_about_certificate(
-                    $category_id,
-                    $user_id,
-                    $my_score_in_gradebook,
-                    api_get_utc_datetime()
-                );
+                register_user_info_about_certificate($category_id, $user_id, $my_score_in_gradebook, api_get_utc_datetime());
                 $my_certificate = get_certificate_by_user_id($cats_course[0]->get_id(), $user_id);
             }
 
             if (!empty($my_certificate)) {
                 $certificate_obj = new Certificate($my_certificate['id']);
 
-                $url          = Certificate::getCertificatePublicURL($my_certificate['id']);
+                $fileWasGenerated = $certificate_obj->html_file_is_generated();
+                $html = null;
+                if (!empty($fileWasGenerated)) {
+                    $url = api_get_path(WEB_PATH) . 'certificates/index.php?id=' . $my_certificate['id'];
                 $certificates = Display::url(
-                    Display::return_icon('certificate.png', get_lang('Certificates'), array(), 32),
+                        Display::return_icon(
+                            'certificate.png',
+                            get_lang('Certificates'),
+                            array(),
+                            32
+                        ),
                     $url,
                     array('target' => '_blank')
                 );
                 $html         = '<div class="actions" align="right">';
-                $html .= Display::url($url, $url, array('target' => '_blank'));
                 $html .= $certificates;
                 $html .= '</div>';
 
+                }
                 return $html;
             }
         } else {

+ 163 - 143
main/gradebook/lib/be/evallink.class.php

@@ -1,160 +1,180 @@
 <?php
 /* For licensing terms, see /license.txt */
+
 /**
  * Class to be used as basis for links referring to Evaluation objects.
  * @author Bert Steppé
  * @package chamilo.gradebook
- */
-/**
- * Class
  * @package chamilo.gradebook
  */
 abstract class EvalLink extends AbstractLink
 {
-
     protected $evaluation = null;
 
-	/**
-	 * Constructor
-	 */
-    function __construct() {
-    	parent::__construct();
+    /**
+     * Constructor
+     */
+    function __construct()
+    {
+        parent::__construct();
     }
+
     // Functions implementing AbstractLink
 
-    public function has_results() {
-    	$eval = $this->get_evaluation();
-		return $eval->has_results();
-    }
-
-    public function calc_score($stud_id = null) {        
-    	$eval = $this->get_evaluation();
-		return $eval->calc_score($stud_id);
-    }
-
-	public function get_link() {
-    	$eval = $this->get_evaluation();
-		// course/platform admin can go to the view_results page
-		if (api_is_allowed_to_edit())
-			return 'gradebook_view_result.php?selecteval=' . $eval->get_id();
-		// students can go to the statistics page (if custom display enabled)
-		elseif (ScoreDisplay :: instance()->is_custom())
-			return 'gradebook_statistics.php?selecteval=' . $eval->get_id();
-		else
-			return null;
-	}
-
-    public function get_name() {
-    	$eval = $this->get_evaluation();
-    	return $eval->get_name();
-    }
-
-    public function get_description() {
-    	$eval = $this->get_evaluation();
-    	return $eval->get_description();
-    }
-
-    public function get_max() {
-    	$eval = $this->get_evaluation();
-    	return $eval->get_max();
-    }
-
-    public function is_valid_link() {
-    	$eval = $this->get_evaluation();
-    	return (isset($eval));
-    }
-	public function needs_name_and_description() {
-		return true;
-	}
-
-	public function needs_max() {
-		return true;
-	}
-
-	public function needs_results() {
-		return true;
-	}
-
-	public function add_linked_data() {
-		if ($this->is_valid_link()) {
-			$this->evaluation->add();
-			$this->set_ref_id($this->evaluation->get_id());
-		}
-	}
-
-	public function save_linked_data() {
-		if ($this->is_valid_link()) {
-			$this->evaluation->save();
-		}
-	}
-
-	public function delete_linked_data() {
-		if ($this->is_valid_link()) {
-			$this->evaluation->delete_with_results();
-		}
-	}
-
-	public function set_name ($name) {
-		if ($this->is_valid_link()) {
-			$this->evaluation->set_name($name);
-		}
-	}
-
-	public function set_description ($description) {
-		if ($this->is_valid_link()) {
-			$this->evaluation->set_description($description);
-		}
-	}
-
-	public function set_max ($max) {
-		if ($this->is_valid_link()) {
-			$this->evaluation->set_max($max);
-		}
-	}
-    
+    public function has_results()
+    {
+        $eval = $this->get_evaluation();
+        return $eval->has_results();
+    }
+
+    public function calc_score($stud_id = null)
+    {
+        $eval = $this->get_evaluation();
+        return $eval->calc_score($stud_id);
+    }
+
+    public function get_link()
+    {
+        $eval = $this->get_evaluation();
+        // course/platform admin can go to the view_results page
+        if (api_is_allowed_to_edit()) {
+            return 'gradebook_view_result.php?selecteval=' . $eval->get_id();
+        } // students can go to the statistics page (if custom display enabled)
+        elseif (ScoreDisplay :: instance()->is_custom()) {
+            return 'gradebook_statistics.php?selecteval=' . $eval->get_id();
+        } else {
+            return null;
+        }
+    }
+
+    public function get_name()
+    {
+        $eval = $this->get_evaluation();
+        return $eval->get_name();
+    }
+
+    public function get_description()
+    {
+        $eval = $this->get_evaluation();
+        return $eval->get_description();
+    }
+
+    public function get_max()
+    {
+        $eval = $this->get_evaluation();
+        return $eval->get_max();
+    }
+
+    public function is_valid_link()
+    {
+        $eval = $this->get_evaluation();
+        return (isset($eval));
+    }
+
+    public function needs_name_and_description()
+    {
+        return true;
+    }
+
+    public function needs_max()
+    {
+        return true;
+    }
+
+    public function needs_results()
+    {
+        return true;
+    }
+
+    public function add_linked_data()
+    {
+        if ($this->is_valid_link()) {
+            $this->evaluation->add();
+            $this->set_ref_id($this->evaluation->get_id());
+        }
+    }
+
+    public function save_linked_data()
+    {
+        if ($this->is_valid_link()) {
+            $this->evaluation->save();
+        }
+    }
+
+    public function delete_linked_data()
+    {
+        if ($this->is_valid_link()) {
+            $this->evaluation->delete_with_results();
+        }
+    }
+
+    public function set_name($name)
+    {
+        if ($this->is_valid_link()) {
+            $this->evaluation->set_name($name);
+        }
+    }
+
+    public function set_description($description)
+    {
+        if ($this->is_valid_link()) {
+            $this->evaluation->set_description($description);
+        }
+    }
+
+    public function set_max($max)
+    {
+        if ($this->is_valid_link()) {
+            $this->evaluation->set_max($max);
+        }
+    }
+
     // Functions overriding non-trivial implementations from AbstractLink
-	public function set_date ($date) {
-		$this->created_at = $date;
-		if ($this->is_valid_link()) {
-			$this->evaluation->set_date($date);
-		}
-	}
-
-	public function set_weight ($weight) {
-		$this->weight = $weight;
-		if ($this->is_valid_link()) {
-			$this->evaluation->set_weight($weight);
-		}
-	}
-
-	public function set_visible ($visible) {
-		$this->visible = $visible;
-		if ($this->is_valid_link()) {
-			$this->evaluation->set_visible($visible);
-		}
-	}
-
-	/**
-	 * Lazy load function to get the linked evaluation
-	 */
-	protected function get_evaluation () {
-		if (!isset($this->evaluation)) {
-			if (isset($this->ref_id)) {
-		    	$evalarray = Evaluation::load($this->get_ref_id());
-				$this->evaluation = $evalarray[0];
-			} else {
-				$eval = new Evaluation();
-				$eval->set_category_id(-1);
-				$eval->set_date(api_get_utc_datetime()); // these values will be changed
-				$eval->set_weight(0);    //   when the link setter
-				$eval->set_visible(0);   //     is called
-				$eval->set_id(-1); // a 'real' id will be set when eval is added to db
-				$eval->set_user_id($this->get_user_id());
-				$eval->set_course_code($this->get_course_code());
-				$this->evaluation = $eval;
-				$this->set_ref_id($eval->get_id());
-			}
-		}
-		return $this->evaluation;
-	}
+    public function set_date($date)
+    {
+        $this->created_at = $date;
+        if ($this->is_valid_link()) {
+            $this->evaluation->set_date($date);
+        }
+    }
+
+    public function set_weight($weight)
+    {
+        $this->weight = $weight;
+        if ($this->is_valid_link()) {
+            $this->evaluation->set_weight($weight);
+        }
+    }
+
+    public function set_visible($visible)
+    {
+        $this->visible = $visible;
+        if ($this->is_valid_link()) {
+            $this->evaluation->set_visible($visible);
+        }
+    }
+
+    /**
+     * Lazy load function to get the linked evaluation
+     */
+    protected function get_evaluation () {
+        if (!isset($this->evaluation)) {
+            if (isset($this->ref_id)) {
+                $evalarray = Evaluation::load($this->get_ref_id());
+                $this->evaluation = $evalarray[0];
+            } else {
+                $eval = new Evaluation();
+                $eval->set_category_id(-1);
+                $eval->set_date(api_get_utc_datetime()); // these values will be changed
+                $eval->set_weight(0);    //   when the link setter
+                $eval->set_visible(0);   //     is called
+                $eval->set_id(-1); // a 'real' id will be set when eval is added to db
+                $eval->set_user_id($this->get_user_id());
+                $eval->set_course_code($this->get_course_code());
+                $this->evaluation = $eval;
+                $this->set_ref_id($eval->get_id());
+            }
+        }
+        return $this->evaluation;
+    }
 }

+ 100 - 54
main/gradebook/lib/be/evaluation.class.php

@@ -1,11 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
- * Defines a gradebook Evaluation object
- * @package chamilo.gradebook
- */
-/**
- * Class
+ * Class Evaluation
  * @package chamilo.gradebook
  */
 class Evaluation implements GradebookItem
@@ -23,108 +19,134 @@ class Evaluation implements GradebookItem
 	private $visible;
     private $evaluation_type_id;
 
-    function __construct() {
+    public function __construct()
+    {
     }
 
     // GETTERS AND SETTERS
 
-   	public function get_id() {
+    public function get_id()
+    {
 		return $this->id;
 	}
 
-	public function get_name() {
+    public function get_name()
+    {
 		return $this->name;
 	}
 
-	public function get_description() {
+    public function get_description()
+    {
 		return $this->description;
 	}
 
-	public function get_user_id() {
+    public function get_user_id()
+    {
 		return $this->user_id;
 	}
 
-	public function get_course_code() {
+    public function get_course_code()
+    {
 		return $this->course_code;
 	}
 
-	public function get_category_id() {
+    public function get_category_id()
+    {
 		return $this->category;
 	}
 
-	public function get_date() {
+    public function get_date()
+    {
 		return $this->created_at;
 	}
 
-	public function get_weight() {
+    public function get_weight()
+    {
 		return $this->weight;
 	}
 
-	public function get_max() {
+    public function get_max()
+    {
 		return $this->eval_max;
 	}
 
-	public function get_type() {
+    public function get_type()
+    {
 		return $this->type;
 	}
 
-	public function is_visible() {
+    public function is_visible()
+    {
 		return $this->visible;
 	}
 
-	public function get_locked() {
+    public function get_locked()
+    {
 		return $this->locked;
 	}
 
-    public function is_locked() {
+    public function is_locked()
+    {
 		return isset($this->locked) && $this->locked == 1 ? true : false ;
 	}
 
-	public function set_id($id) {
+    public function set_id($id)
+    {
 		$this->id = $id;
 	}
 
-	public function set_name ($name) {
+    public function set_name($name)
+    {
 		$this->name = $name;
 	}
 
-	public function set_description ($description) {
+    public function set_description($description)
+    {
 		$this->description = $description;
 	}
 
-	public function set_user_id ($user_id) {
+    public function set_user_id($user_id)
+    {
 		$this->user_id = $user_id;
 	}
 
-	public function set_course_code ($course_code) {
+    public function set_course_code($course_code)
+    {
 		$this->course_code = $course_code;
 	}
 
-	public function set_category_id ($category_id) {
+    public function set_category_id($category_id)
+    {
 		$this->category = $category_id;
 	}
 
-	public function set_date ($date) {
+    public function set_date($date)
+    {
 		$this->created_at = $date;
 	}
 
-	public function set_weight ($weight) {
+    public function set_weight($weight)
+    {
 		$this->weight = $weight;
 	}
 
-	public function set_max ($max) {
+    public function set_max($max)
+    {
 		$this->eval_max = $max;
 	}
 
-	public function set_visible ($visible) {
+    public function set_visible($visible)
+    {
 		$this->visible = $visible;
 	}
 
-    public function set_type ($type) {
+    public function set_type($type)
+    {
 		$this->type = $type;
 	}
 
-	public function set_locked ($locked) {
+    public function set_locked($locked)
+    {
 		$this->locked = $locked;
 	}
 
@@ -140,13 +162,20 @@ class Evaluation implements GradebookItem
 
 	/**
 	 * Retrieve evaluations and return them as an array of Evaluation objects
-	 * @param $id evaluation id
-	 * @param $user_id user id (evaluation owner)
-	 * @param $course_code course code
-	 * @param $category_id parent category
+	 * @param int $id evaluation id
+	 * @param int $user_id user id (evaluation owner)
+	 * @param string $course_code course code
+	 * @param int $category_id parent category
 	 * @param $visible visible
 	 */
-	public static function load($id = null, $user_id = null, $course_code = null, $category_id = null, $visible = null, $locked = null, $name = null) {
+    public static function load(
+        $id = null,
+        $user_id = null,
+        $course_code = null,
+        $category_id = null,
+        $visible = null,
+        $locked = null
+    ) {
     	$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
 		$sql = 'SELECT * FROM '.$tbl_grade_evaluations;
 		$paramcount = 0;
@@ -195,7 +224,8 @@ class Evaluation implements GradebookItem
 		return $alleval;
 	}
 
-    private static function create_evaluation_objects_from_sql_result($result) {
+    private static function create_evaluation_objects_from_sql_result($result)
+    {
     	$alleval=array();
     	if (Database::num_rows($result)) {
     		while ($data = Database::fetch_array($result)) {
@@ -222,7 +252,8 @@ class Evaluation implements GradebookItem
     /**
      * Insert this evaluation into the database
      */
-    public function add() {
+    public function add()
+    {
 		if (isset($this->name) && isset($this->user_id) && isset($this->weight) && isset ($this->eval_max) && isset($this->visible)) {
 			$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
 
@@ -271,7 +302,8 @@ class Evaluation implements GradebookItem
 		}
 	}
 
-	public function add_evaluation_log($idevaluation){
+	public function add_evaluation_log($idevaluation)
+    {
 		if (!empty($idevaluation)) {
 			$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
 			$tbl_grade_linkeval_log = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINKEVAL_LOG);
@@ -292,7 +324,8 @@ class Evaluation implements GradebookItem
 	/**
 	 * Update the properties of this evaluation in the database
 	 */
-	public function save() {
+	public function save()
+    {
 		$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
 		$sql = 'UPDATE '.$tbl_grade_evaluations
 			." SET name = '".Database::escape_string($this->get_name())."'"
@@ -329,7 +362,8 @@ class Evaluation implements GradebookItem
 	/**
 	 * Delete this evaluation from the database
 	 */
-	public function delete() {
+	public function delete()
+    {
 		$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
 		$sql = 'DELETE FROM '.$tbl_grade_evaluations.' WHERE id = '.intval($this->id);
 		Database::query($sql);
@@ -340,7 +374,8 @@ class Evaluation implements GradebookItem
 	 * @param $name name to check (if not given, the name property of this object will be checked)
 	 * @param $parent parent category
 	 */
-	public function does_name_exist($name, $parent) {
+	public function does_name_exist($name, $parent)
+    {
 		if (!isset ($name)) {
 			$name = $this->name;
 			$parent = $this->category;
@@ -420,12 +455,13 @@ class Evaluation implements GradebookItem
 
 	/**
 	 * Calculate the score of this evaluation
-	 * @param $stud_id student id (default: all students who have results for this eval - then the average is returned)
+	 * @param int $stud_id (default: all students who have results for this eval - then the average is returned)
 	 * @return	array (score, max) if student is given
 	 * 			array (sum of scores, number of scores) otherwise
 	 * 			or null if no scores available
 	 */
-    public function calc_score ($stud_id = null) {
+    public function calc_score($stud_id = null)
+    {
 		$results = Result::load(null,$stud_id,$this->id);
 
 		$rescount = 0;
@@ -487,7 +523,8 @@ class Evaluation implements GradebookItem
 	/**
 	 * Internal function used by get_target_categories()
 	 */
-	private function add_target_subcategories($targets, $level, $catid) {
+	private function add_target_subcategories($targets, $level, $catid)
+    {
 		$subcats = Category::load(null,null,null,$catid);
 		foreach ($subcats as $cat) {
 			$targets[] = array ($cat->get_id(), $cat->get_name(), $level+1);
@@ -502,7 +539,8 @@ class Evaluation implements GradebookItem
 	 * If this evaluation moves from inside a course to outside,
 	 * its course code is also changed.
 	 */
-	public function move_to_cat ($cat) {
+	public function move_to_cat($cat)
+    {
 		$this->set_category_id($cat->get_id());
 		if ($this->get_course_code() != $cat->get_course_code()) {
 			$this->set_course_code($cat->get_course_code());
@@ -516,7 +554,8 @@ class Evaluation implements GradebookItem
 	 * @param $cat_id parent category (use 'null' to retrieve them in all categories)
 	 * @param $stud_id student id
 	 */
-    public function get_evaluations_with_result_for_student ($cat_id = null, $stud_id) {
+    public function get_evaluations_with_result_for_student ($cat_id = null, $stud_id)
+    {
 		$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
     	$tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
 
@@ -541,7 +580,8 @@ class Evaluation implements GradebookItem
     /**
      * Get a list of students that do not have a result record for this evaluation
      */
-    public function get_not_subscribed_students ($first_letter_user = '') {
+    public function get_not_subscribed_students ($first_letter_user = '')
+    {
 		$tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
     	$tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
 
@@ -565,7 +605,8 @@ class Evaluation implements GradebookItem
      * @return array evaluation objects matching the search criterium
      * @todo can be written more efficiently using a new (but very complex) sql query
      */
-    public function find_evaluations ($name_mask,$selectcat) {
+    public function find_evaluations ($name_mask,$selectcat)
+    {
     	$rootcat = Category::load($selectcat);
 		$evals = $rootcat[0]->get_evaluations((api_is_allowed_to_create_course() ? null : api_get_user_id()), true);
 		$foundevals = array();
@@ -578,11 +619,13 @@ class Evaluation implements GradebookItem
     }
 
     // Other methods implementing GradebookItem
-    public function get_item_type() {
+    public function get_item_type()
+    {
 		return 'E';
 	}
 
-	public function get_icon_name() {
+	public function get_icon_name()
+    {
 		return $this->has_results() ? 'evalnotempty' : 'evalempty';
 	}
 
@@ -591,13 +634,15 @@ class Evaluation implements GradebookItem
   	 * @param int locked 1 or unlocked 0
   	 *
   	 **/
-  	function lock($locked) {
+  	function lock($locked)
+    {
   		$table_evaluation = Database::get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
   		$sql = "UPDATE $table_evaluation SET locked = '".intval($locked)."' WHERE id='".intval($this->id)."'";
   		Database::query($sql);
   	}
 
-    function check_lock_permissions() {
+    function check_lock_permissions()
+    {
         if (api_is_platform_admin()) {
             return true;
         } else {
@@ -607,7 +652,8 @@ class Evaluation implements GradebookItem
         }
     }
 
-    function delete_linked_data() {
+    function delete_linked_data()
+    {
 
     }
 }

+ 39 - 17
main/gradebook/lib/be/exerciselink.class.php

@@ -18,7 +18,10 @@ class ExerciseLink extends AbstractLink
     private $is_hp;
 
     // CONSTRUCTORS
-    function __construct($hp=0) 
+    /**
+     * @param int $hp
+     */
+    public function __construct($hp = 0)
     {
     	parent::__construct();
     	$this->set_type(LINK_EXERCISE);
@@ -34,7 +37,8 @@ class ExerciseLink extends AbstractLink
 	 * Generate an array of exercises that a teacher hasn't created a link for.
 	 * @return array 2-dimensional array - every element contains 2 subelements (id, name)
 	 */
-    public function get_not_created_links() {
+    public function get_not_created_links()
+    {
         return false;
     	if (empty($this->course_code)) {
             die('Error in get_not_created_links() : course code not set');
@@ -61,7 +65,8 @@ class ExerciseLink extends AbstractLink
 	 * Generate an array of all exercises available.
 	 * @return array 2-dimensional array - every element contains 2 subelements (id, name)
 	 */
-    public function get_all_links() {
+    public function get_all_links()
+    {
         $TBL_DOCUMENT = Database :: get_course_table(TABLE_DOCUMENT);
         $TBL_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);
         $documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code."/document";
@@ -74,6 +79,7 @@ class ExerciseLink extends AbstractLink
         } else {
             $session_condition = api_get_session_condition($session_id, true, true);
         }        
+        $uploadPath = null;
         
 		$sql = 'SELECT id,title from '.$this->get_exercise_table().' 
 				WHERE c_id = '.$this->course_id.' AND active=1  '.$session_condition;        
@@ -104,7 +110,7 @@ class ExerciseLink extends AbstractLink
             }
         }
         if (isset($result2)) {
-            if (mysql_numrows($result2) > 0) {
+            if (Database::num_rows($result2) > 0) {
         		while ($row=Database::fetch_array($result2)) {
                     /*$path = $data['path'];
                     $fname = GetQuizName($path,$documentPath);
@@ -113,7 +119,6 @@ class ExerciseLink extends AbstractLink
                     $attribute['visibility'][] = $row['visibility'];
                     $attribute['comment'][] = $row['comment'];
                     $attribute['id'] = $row['id'];
-        		}
                 if (isset($attribute['path']) && is_array($attribute['path'])) {
                     $hotpotatoes_exist = true;
                     while (list($key, $path) = each($attribute['path'])) {
@@ -123,6 +128,7 @@ class ExerciseLink extends AbstractLink
                             $title = basename($path);
                         }
                         $cats[] = array ($attribute['id'], $title.'(HP)');
+                        }
                     }
                 }
             }
@@ -210,7 +216,8 @@ class ExerciseLink extends AbstractLink
      * First we go to exercise_jump.php and then to the result page.
      * Check this php file for more info.
      */
-	public function get_link() {
+    public function get_link()
+    {
 		//status student
 		$user_id = api_get_user_id();
 		//$course_code = $this->get_course_code();
@@ -226,7 +233,8 @@ class ExerciseLink extends AbstractLink
     /**
      * Get name to display: same as exercise title
      */
-    public function get_name() {
+    public function get_name()
+    {
         $documentPath = api_get_path(SYS_COURSE_PATH).$this->course_code."/document";
         require_once api_get_path(SYS_CODE_PATH).'exercice/hotpotatoes.lib.php';
     	$data = $this->get_exercise_data();        
@@ -247,9 +255,10 @@ class ExerciseLink extends AbstractLink
     /**
      * Get description to display: same as exercise description
      */
-    public function get_description() {
+    public function get_description()
+    {
     	$data = $this->get_exercise_data();
-    	return $data['description'];
+    	return isset($data['description']) ? $data['description'] : null;
     }
 
     /**
@@ -263,23 +272,30 @@ class ExerciseLink extends AbstractLink
 		return ($number[0] != 0);
     }
 
-    public function get_type_name() {
+    /**
+     * @return array|string
+     */
+    public function get_type_name()
+    {
         if ($this->is_hp == 1) {
-            return get_lang('Hopotatoe');
+            return get_lang('HotPotatoes');
         } else {
     	return get_lang('Quiz');
     }
 
     }
-	public function needs_name_and_description() {
+	public function needs_name_and_description()
+    {
 		return false;
 	}
 
-	public function needs_max() {
+	public function needs_max()
+    {
 		return false;
 	}
 
-	public function needs_results() {
+	public function needs_results()
+    {
 		return false;
 	}
 
@@ -293,7 +309,8 @@ class ExerciseLink extends AbstractLink
     /**
      * Lazy load function to get the database table of the exercise
      */
-    private function get_exercise_table() {
+    private function get_exercise_table()
+    {
     	$this->exercise_table = Database :: get_course_table(TABLE_QUIZ_TEST);
     	return $this->exercise_table;   		
     }
@@ -301,7 +318,8 @@ class ExerciseLink extends AbstractLink
     /**
      * Lazy load function to get the database contents of this exercise
      */
-    private function get_exercise_data() {
+    private function get_exercise_data()
+    {
         if ($this->is_hp == 1) {
            $tbl_exercise = Database :: get_course_table(TABLE_DOCUMENT); 
            $TBL_ITEM_PROPERTY = Database :: get_course_table(TABLE_ITEM_PROPERTY);           
@@ -326,7 +344,11 @@ class ExerciseLink extends AbstractLink
     	return $this->exercise_data;
     }
 
-    public function get_icon_name() {
+    /**
+     * @return string
+     */
+    public function get_icon_name()
+    {
 		return 'exercise';
 	}
 }

+ 47 - 30
main/gradebook/lib/be/linkfactory.class.php

@@ -1,12 +1,5 @@
 <?php
 /* For licensing terms, see /license.txt */
-/**
- * Script
- * @package chamilo.gradebook
- */
-/**
- * Init
- */
 // To add your new link type here:
 // - define a unique type id
 // - add include
@@ -24,6 +17,7 @@ require_once 'attendancelink.class.php';
 require_once 'surveylink.class.php';
 
 /**
+ * Class LinkFactory
  * Factory for link objects
  * @author Bert Steppé
  * @package chamilo.gradebook
@@ -33,22 +27,39 @@ class LinkFactory
 
 	/**
 	 * Retrieve links and return them as an array of extensions of AbstractLink.
-	 * @param $id link id
-	 * @param $type link type
-	 * @param $ref_id reference id
-	 * @param $user_id user id (link owner)
-	 * @param $course_code course code
-	 * @param $category_id parent category
-	 * @param $visible visible
+	 * @param int $id link id
+	 * @param int $type link type
+	 * @param int $ref_id reference id
+	 * @param int $user_id user id (link owner)
+	 * @param string $course_code course code
+	 * @param int $category_id parent category
+	 * @param int $visible visible
 	 */
-	public static function load ($id = null, $type = null, $ref_id = null, $user_id = null, $course_code = null, $category_id = null, $visible = null) {
-		return AbstractLink::load($id, $type, $ref_id, $user_id, $course_code, $category_id, $visible);
+    public static function load(
+        $id = null,
+        $type = null,
+        $ref_id = null,
+        $user_id = null,
+        $course_code = null,
+        $category_id = null,
+        $visible = null
+    ) {
+        return AbstractLink::load(
+            $id,
+            $type,
+            $ref_id,
+            $user_id,
+            $course_code,
+            $category_id,
+            $visible
+        );
 	}
 
 	/**
 	 * Get the link object referring to an evaluation
 	 */
-	public function get_evaluation_link ($eval_id) {
+	public function get_evaluation_link ($eval_id)
+    {
 		$links = AbstractLink :: load(null, null, $eval_id);
 		foreach ($links as $link) {
 			if (is_a($link, 'EvalLink')) {
@@ -63,7 +74,8 @@ class LinkFactory
      * @param string $name_mask search string
      * @return array link objects matching the search criterium
      */
-    public function find_links ($name_mask,$selectcat) {
+    public function find_links ($name_mask,$selectcat)
+    {
     	return AbstractLink::find_links($name_mask,$selectcat);
     }
 
@@ -71,7 +83,8 @@ class LinkFactory
 	 * Static method to create specific link objects
 	 * @param $type link type
 	 */
-	public static function create ($type) {
+	public static function create ($type)
+    {
         $type = intval($type);
 		switch ($type) {
 			case LINK_EXERCISE:
@@ -96,21 +109,25 @@ class LinkFactory
 
 	/**
 	 * Return an array of all known link types
+     * @return array
 	 */
-	public static function get_all_types () {
+	public static function get_all_types ()
+    {
 		//LINK_DROPBOX,
-		return array (LINK_EXERCISE,
-					  //LINK_DROPBOX,
-                      LINK_HOTPOTATOES,
-					  LINK_STUDENTPUBLICATION,
-					  LINK_LEARNPATH,
-                      LINK_FORUM_THREAD,
-                      LINK_ATTENDANCE,
-                      LINK_SURVEY
-					  );
+		return array (
+			LINK_EXERCISE,
+			//LINK_DROPBOX,
+			LINK_HOTPOTATOES,
+			LINK_STUDENTPUBLICATION,
+			LINK_LEARNPATH,
+			LINK_FORUM_THREAD,
+			LINK_ATTENDANCE,
+			LINK_SURVEY
+		);
 	}
 
-    public function delete() {
+    public function delete()
+    {
 
     }
 

+ 38 - 31
main/gradebook/lib/be/result.class.php

@@ -22,49 +22,60 @@ class Result
 
 // CONSTRUCTORS
 
-    function Result() {
+    function Result()
+    {
 		$this->created_at = api_get_utc_datetime();
     }
 
 // GETTERS AND SETTERS
 
-   	public function get_id() {
+    public function get_id()
+    {
 		return $this->id;
 	}
 
-   	public function get_user_id() {
+    public function get_user_id()
+    {
 		return $this->user_id;
 	}
 
-   	public function get_evaluation_id() {
+    public function get_evaluation_id()
+    {
 		return $this->evaluation;
 	}
 
-    public function get_date() {
+    public function get_date()
+    {
 		return $this->created_at;
 	}
 
-   	public function get_score() {
+    public function get_score()
+    {
 		return $this->score;
 	}
 
-    public function set_id ($id) {
+    public function set_id($id)
+    {
 		$this->id = $id;
 	}
 
-   	public function set_user_id ($user_id) {
+    public function set_user_id($user_id)
+    {
 		$this->user_id = $user_id;
 	}
 
-   	public function set_evaluation_id ($evaluation_id) {
+    public function set_evaluation_id($evaluation_id)
+    {
 		$this->evaluation = $evaluation_id;
 	}
 
-    public function set_date ($creation_date) {
+    public function set_date($creation_date)
+    {
 		$this->created_at = $creation_date;
 	}
 
-   	public function set_score ($score) {
+    public function set_score($score)
+    {
 		$this->score = $score;
 	}
 
@@ -76,7 +87,9 @@ class Result
 	 * @param $user_id user id (student)
 	 * @param $evaluation_id evaluation where this is a result for
 	 */
-	public static function load ($id = null, $user_id = null, $evaluation_id = null) {
+    public static function load($id = null, $user_id = null, $evaluation_id = null)
+    {
+        $tbl_user = Database :: get_main_table(TABLE_MAIN_USER);
 		$tbl_grade_results 				= Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
 		$tbl_course_rel_course 			= Database :: get_main_table(TABLE_MAIN_COURSE_USER);
 		$tbl_session_rel_course_user 	= Database :: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
@@ -89,6 +102,7 @@ class Result
 
 			if ($info_verified_if_exist_evaluation != 0 ) {
 
+                $sql_course_rel_user = '';
 				if (api_get_session_id()) {
 					$sql_course_rel_user = 'SELECT course_code, id_user as user_id, status
 					                        FROM '.$tbl_session_rel_course_user.'
@@ -120,10 +134,12 @@ class Result
 			}
 		}
 
-		$sql = 'SELECT id,user_id,evaluation_id,created_at,score FROM '.$tbl_grade_results;
+        $sql = "SELECT gr.id, gr.user_id, gr.evaluation_id, gr.created_at, gr.score 
+                FROM $tbl_grade_results gr
+                LEFT JOIN $tbl_user u ON gr.user_id = u.user_id ";
 		$paramcount = 0;
 		if (!empty ($id)) {
-			$sql.= ' WHERE id = '.Database::escape_string($id);
+            $sql.= ' WHERE gr.id = ' . Database::escape_string($id);
 			$paramcount ++;
 		}
 		if (!empty ($user_id)) {
@@ -178,25 +194,14 @@ class Result
 			Database::query($sql);
 		} else {
 			die('Error in Result add: required field empty');
-		}
-
-	}
-        /**
-         * Group insertion assuming all data is correct
-         */
-        public function group_add($list) {
-	    $tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
-            $sql = "INSERT INTO $tbl_grade_results (user_id, evaluation_id, created_at, score) VALUES ";
-            foreach ($list as $row) {
-                $sql.= "(".intval($row['user_id']).",".$row['evaluation_id'].",'".$row['created_at']."','".$row['score']."'),";
-            }
-            $sql = substr($sql,0,-1);
-            $res = Database::query($sql);
         }
+	}
+
 	/**
 	 * insert log result
 	 */
-	 public function add_result__log($userid,$evaluationid){
+    public function add_result__log($userid, $evaluationid)
+    {
 
 	 	if (isset($userid) && isset($evaluationid) ) {
 			$tbl_grade_results_log = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT_LOG);
@@ -226,7 +231,8 @@ class Result
 	/**
 	 * Update the properties of this result in the database
 	 */
-	public function save() {
+    public function save()
+    {
 		$tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
 		$sql = 'UPDATE '.$tbl_grade_results.'
                 SET user_id = '.$this->get_user_id()
@@ -245,7 +251,8 @@ class Result
 	/**
 	 * Delete this result from the database
 	 */
-	public function delete() {
+    public function delete()
+    {
 		$tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
 		$sql = 'DELETE FROM '.$tbl_grade_results.' WHERE id = '.$this->id;
 		Database::query($sql);

+ 173 - 43
main/gradebook/lib/fe/catform.class.php

@@ -1,22 +1,18 @@
 <?php
 /* For licensing terms, see /license.txt */
-/**
- * Script
- * @package chamilo.gradebook
- */
-/**
- * Init
- */
+
 require_once dirname(__FILE__).'/../../../inc/global.inc.php';
 require_once dirname(__FILE__).'/../be.inc.php';
 
 /**
- * Extends formvalidator with add&edit forms
+ * Class CatForm
+ *
  * @author Stijn Konings
  * @package chamilo.gradebook
  */
 
-class CatForm extends FormValidator {
+class CatForm extends FormValidator
+{
 
     const TYPE_ADD              = 1;
     const TYPE_EDIT             = 2;
@@ -32,7 +28,13 @@ class CatForm extends FormValidator {
 	 * @param string form name
 	 * @param method method
 	 */
-    function CatForm($form_type, $category_object,$form_name,$method = 'post',$action=null) {
+    public function CatForm(
+        $form_type,
+        $category_object,
+        $form_name,
+        $method = 'post',
+        $action = null
+    ) {
 		parent :: __construct($form_name, $method, $action);
     	$this->form_type = $form_type;
     	if (isset ($category_object)) {
@@ -54,12 +56,19 @@ class CatForm extends FormValidator {
 	 * This function will build a move form that will allow the user to move a category to
 	 * a another
 	 */
-   	protected function build_move_form() {
+    protected function build_move_form()
+    {
 		$renderer =& $this->defaultRenderer();
 		$renderer->setElementTemplate('<span>{element}</span> ');
-		$this->addElement('static',null,null,'"'.$this->category_object->get_name().'" ');
+        $this->addElement(
+            'static',
+            null,
+            null,
+            '"' . $this->category_object->get_name() . '" '
+        );
 		$this->addElement('static',null,null,get_lang('MoveTo'). ' : ');
 		$select = $this->addElement('select','move_cat',null,null);
+        $line = null;
 		foreach ($this->category_object->get_target_categories() as $cat) {
 			for ($i=0;$i<$cat[2];$i++) {
 				$line .= '--';
@@ -77,12 +86,15 @@ class CatForm extends FormValidator {
 	 * This function builds an 'add category form, if parent id is 0, it will only
 	 * show courses
 	 */
-   	protected function build_add_form() {
+    protected function build_add_form()
+    {
 		//check if we are a root category
 		//if so, you can only choose between courses
 		if ($this->category_object->get_parent_id() == '0') {
 			//$select = $this->addElement('select','select_course',array(get_lang('PickACourse'),'test'), null);
-			$coursecat = Category :: get_not_created_course_categories(api_get_user_id());
+            $coursecat = Category :: get_not_created_course_categories(
+                api_get_user_id()
+            );
 			if (count($coursecat)==0) {
 				//$select->addoption(get_lang('CourseIndependent'),'COURSEINDEPENDENT','disabled');
 			} else {
@@ -96,17 +108,26 @@ class CatForm extends FormValidator {
 			} else {
 				//$select->addoption($row[1],$row[0]);
 			}
-   			$this->setDefaults(array(
-   				'select_course' => $this->category_object->get_course_code(),
+            $this->setDefaults(
+                array(
+                    'select_course' => $this->category_object->get_course_code(
+                    ),
    			   'hid_user_id' => $this->category_object->get_user_id(),
    			   'hid_parent_id' => $this->category_object->get_parent_id()
-   			));
+                )
+            );
 		} else {
-   			$this->setDefaults(array(
+            $this->setDefaults(
+                array(
    		    'hid_user_id' => $this->category_object->get_user_id(),
    		    'hid_parent_id' => $this->category_object->get_parent_id()
-   		    ));
-   		    $this->addElement('hidden','course_code', $this->category_object->get_course_code());
+                )
+            );
+            $this->addElement(
+                'hidden',
+                'course_code',
+                $this->category_object->get_course_code()
+            );
 		}
    		$this->build_basic_form();
    	}
@@ -114,12 +135,21 @@ class CatForm extends FormValidator {
 	/**
 	 * Builds an form to edit a category
 	 */
-   	protected function build_editing_form() {
+    protected function build_editing_form()
+    {
    	    $skills = $this->category_object->get_skills_for_select();      
         $course_code = api_get_course_id();
         $session_id = api_get_session_id();
          //Freeze or not
-        $test_cats  = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init	
+        $test_cats = Category::load(
+            null,
+            null,
+            $course_code,
+            null,
+            null,
+            $session_id,
+            false
+        ); //already init
         $links = null;
         if (isset($test_cats[0])) {
             $links = $test_cats[0]->get_links();
@@ -153,17 +183,32 @@ class CatForm extends FormValidator {
             )
         );
    		$this->addElement('hidden','hid_id', $this->category_object->get_id());
-   		$this->addElement('hidden','course_code', $this->category_object->get_course_code());
+        $this->addElement(
+            'hidden',
+            'course_code',
+            $this->category_object->get_course_code()
+        );
 		$this->build_basic_form();
    	}
 
-   	private function build_basic_form() {
+    /**
+     *
+     */
+    private function build_basic_form()
+    {
    	    
 		$this->addElement('hidden', 'zero', 0);
-		$this->add_textfield('name', get_lang('CategoryName'), true, array('class'=>'span3','maxlength'=>'50'));        
+        $this->add_textfield(
+            'name',
+            get_lang('CategoryName'),
+            true,
+            array('class' => 'span3', 'maxlength' => '50')
+        );
 		$this->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
 		
-		if (isset($this->category_object) && $this->category_object->get_parent_id() == 0) {
+        if (isset($this->category_object) &&
+            $this->category_object->get_parent_id() == 0
+        ) {
 			//we can't change the root category
 			$this->freeze('name');
 		}	
@@ -183,31 +228,90 @@ class CatForm extends FormValidator {
             
                 //the magic should be here            
                 $skills = $this->category_object->get_skills();    
-                $this->addElement('select', 'skills', array(get_lang('Skills'), get_lang('SkillsAchievedWhenAchievingThisGradebook')), null, array('id'=>'skills', 'multiple'=>'multiple'));
+                $skillToSelect = array();
+                foreach ($skills as $skill) {
+                    $skillToSelect[$skill['id']] = $skill['name'];
+                }
+
+                $this->addElement(
+                    'select',
+                    'skills',
+                    array(
+                        get_lang('Skills'),
+                        get_lang('SkillsAchievedWhenAchievingThisGradebook')
+                    ),
+                    $skillToSelect,
+                    array('id' => 'skills', 'multiple' => 'multiple')
+                );
                 $content = '';
                 if (!empty($skills)) {
                     foreach($skills as $skill) {                    
-                        $content .= Display::tag('li', $skill['name'].'<a id="deleteskill_'.$skill['id'].'" class="closebutton" href="#"></a>', array('id'=>'skill_'.$skill['id'], 'class'=>'bit-box')); 
+                        $content .= Display::tag(
+                            'li',
+                            $skill['name'] . '<a id="deleteskill_' . $skill['id'] . '" class="closebutton" href="#"></a>',
+                            array(
+                                'id' => 'skill_' . $skill['id'],
+                                'class' => 'bit-box'
+                            )
+                        );
                     }
                 }
-                $this->addElement('label', null, Display::tag('ul', $content, array('class'=>'holder holder_simple')));            
+                $this->addElement(
+                    'label',
+                    null,
+                    Display::tag(
+                        'ul',
+                        $content,
+                        array('class' => 'holder holder_simple')
+                    )
+                );
             }
         }
         
-		if (isset($this->category_object) && $this->category_object->get_parent_id() == 0) {					
-			$this->add_textfield('certif_min_score', get_lang('CertificateMinScore'),false,array('class'=>'span1','maxlength'=>'5'));
-			$this->addRule('certif_min_score', get_lang('ThisFieldIsRequired'), 'required');
-			$this->addRule('certif_min_score',get_lang('OnlyNumbers'),'numeric');			
-			$this->addRule(array('certif_min_score', 'zero'), get_lang('NegativeValue'), 'compare', '>=');
+        if (isset($this->category_object) && $this->category_object->get_parent_id(
+            ) == 0
+        ) {
+            $this->add_textfield(
+                'certif_min_score',
+                get_lang('CertificateMinScore'),
+                false,
+                array('class' => 'span1', 'maxlength' => '5')
+            );
+            $this->addRule(
+                'certif_min_score',
+                get_lang('ThisFieldIsRequired'),
+                'required'
+            );
+            $this->addRule(
+                'certif_min_score',
+                get_lang('OnlyNumbers'),
+                'numeric'
+            );
+            $this->addRule(
+                array('certif_min_score', 'zero'),
+                get_lang('NegativeValue'),
+                'compare',
+                '>='
+            );
 		} else {
 		    $this->addElement('checkbox', 'visible', null, get_lang('Visible'));
 		}		
 		
    		$this->addElement('hidden','hid_user_id');
    		$this->addElement('hidden','hid_parent_id');
-		$this->addElement('textarea', 'description', get_lang('Description'), array('class'=>'span3','cols' => '34'));        
+        $this->addElement(
+            'textarea',
+            'description',
+            get_lang('Description'),
+            array('class' => 'span3', 'cols' => '34')
+        );
                 
-        if (isset($this->category_object) && $this->category_object->get_parent_id() == 0 && (api_is_platform_admin() || api_get_setting('teachers_can_change_grade_model_settings') == 'true')) {
+        if (isset($this->category_object) &&
+            $this->category_object->get_parent_id() == 0 &&
+            (api_is_platform_admin() || api_get_setting(
+                    'teachers_can_change_grade_model_settings'
+                ) == 'true')
+        ) {
             
             //Getting grade models
             $obj = new GradeModel();
@@ -226,7 +330,15 @@ class CatForm extends FormValidator {
             //Freeze or not
             $course_code = api_get_course_id();
             $session_id = api_get_session_id();
-            $test_cats  = Category :: load(null, null, $course_code, null, null, $session_id, false); //already init	
+            $test_cats = Category :: load(
+                null,
+                null,
+                $course_code,
+                null,
+                null,
+                $session_id,
+                false
+            ); //already init
             $links = null;
             if (!empty($test_cats[0])) {
                 $links = $test_cats[0]->get_links();            
@@ -240,16 +352,31 @@ class CatForm extends FormValidator {
         }
                 
 		if ($this->form_type == self :: TYPE_ADD) {
-			$this->addElement('style_submit_button', null, get_lang('AddCategory'), 'class="save"');
+            $this->addElement(
+                'style_submit_button',
+                null,
+                get_lang('AddCategory'),
+                'class="save"'
+            );
 		} else {
 			$this->addElement('hidden','editcat', intval($_GET['editcat']));
-			$this->addElement('style_submit_button', null, get_lang('EditCategory'), 'class="save"');
+            $this->addElement(
+                'style_submit_button',
+                null,
+                get_lang('EditCategory'),
+                'class="save"'
+            );
 		}
         
 		//if (!empty($grading_contents)) {
 			$this->addRule('weight', get_lang('OnlyNumbers'), 'numeric');
 			//$this->addRule('weight',get_lang('NoDecimals'),'nopunctuation');
-			$this->addRule(array ('weight', 'zero'), get_lang('NegativeValue'), 'compare', '>=');
+        $this->addRule(
+            array('weight', 'zero'),
+            get_lang('NegativeValue'),
+            'compare',
+            '>='
+        );
 		//}
             
         $setting = api_get_setting('tool_visible_by_default_at_creation');   
@@ -264,7 +391,8 @@ class CatForm extends FormValidator {
 	 * This function builds an 'select course' form in the add category process,
 	 * if parent id is 0, it will only show courses
 	 */
-   	protected function build_select_course_form() {
+    protected function build_select_course_form()
+    {
 		$select = $this->addElement('select','select_course',array(get_lang('PickACourse'),'test'), null);
 		$coursecat = Category :: get_all_courses(api_get_user_id());
 		//only return courses that are not yet created by the teacher
@@ -281,11 +409,13 @@ class CatForm extends FormValidator {
 		$this->addElement('submit', null, get_lang('Ok'));
    	}
 
-   	function display() {
+    function display()
+    {
    		parent :: display();
    	}
 
-   	function setDefaults($defaults = array(), $filter = null) {
+    function setDefaults($defaults = array(), $filter = null)
+    {
    		parent :: setDefaults($defaults, $filter);
    	}
 }

+ 44 - 16
main/gradebook/lib/fe/displaygradebook.php

@@ -17,7 +17,9 @@ class DisplayGradebook
 	* @param $shownavbar 1=show navigation bar
 	* @param $forpdf only output for pdf file
 	*/
-	static function display_header_result($evalobj, $selectcat, $page) {
+    static function display_header_result($evalobj, $selectcat, $page)
+    {
+        $header = null;
 		if (api_is_allowed_to_edit(null, true)) {
 			$header = '<div class="actions">';
 			if ($page != 'statistics') {
@@ -60,6 +62,7 @@ class DisplayGradebook
 
         $student_score = '';
 
+        $average = "";
 		if (($evalobj->has_results())){ // TODO this check needed ?
 			$score = $evalobj->calc_score();
 
@@ -70,6 +73,7 @@ class DisplayGradebook
             }
 		}
 
+        $description = "";
 		if (!$evalobj->get_description() == '') {
 			$description= get_lang('Description') . ' :<b> ' . $evalobj->get_description() . '</b><br>';
 		}
@@ -116,7 +120,8 @@ class DisplayGradebook
 	* @param $showeval
 	* @param $showlink
 	*/
-	function display_header_flatview($catobj, $showeval, $showlink,$simple_search_form) {
+    function display_header_flatview($catobj, $showeval, $showlink, $simple_search_form)
+    {
 		$header= '<table border="0" cellpadding="5">';
 		$header .= '<td style="vertical-align: top;"><a href="'.Security::remove_XSS($_SESSION['gradebook_dest']).'?selectcat=' . Security::remove_XSS($_GET['selectcat']) . '">' . Display::return_icon('gradebook.gif') . get_lang('Gradebook') . '</a></td>';
 		$header .= '<td style="vertical-align: top;">' . get_lang('FilterCategory') . '</td><td style="vertical-align: top;"><form name="selector"><select name="selectcat" onchange="document.selector.submit()">';
@@ -163,7 +168,8 @@ class DisplayGradebook
 	* @param $showeval
 	* @param $showlink
 	*/
-	static function display_header_reduce_flatview($catobj, $showeval, $showlink,$simple_search_form) {
+    static function display_header_reduce_flatview($catobj, $showeval, $showlink, $simple_search_form)
+    {
 		$header = '<div class="actions">';
         if ($catobj->get_parent_id() == 0) {
             $select_cat = $catobj->get_id();
@@ -190,7 +196,8 @@ class DisplayGradebook
 		echo $header;
 	}
 
-	function display_header_gradebook_per_gradebook($catobj, $showtree, $selectcat, $is_course_admin, $is_platform_admin, $simple_search_form, $show_add_qualification = true, $show_add_link = true) {
+    function display_header_gradebook_per_gradebook($catobj, $showtree, $selectcat, $is_course_admin, $is_platform_admin, $simple_search_form, $show_add_qualification = true, $show_add_link = true)
+    {
 		// Student
 		$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
 		$objcat = new Category();
@@ -353,15 +360,28 @@ class DisplayGradebook
 
 	/**
 	 * Displays the header for the gradebook containing the navigation tree and links
-	 * @param category_object $currentcat
+     * @param Category $currentcat
 	 * @param int $showtree '1' will show the browse tree and naviation buttons
 	 * @param boolean $is_course_admin
 	 * @param boolean $is_platform_admin
-     * @param boolean Whether to show or not the link to add a new qualification (we hide it in case of the course-embedded tool where we have only one calification per course or session)
-     * @param boolean Whether to show or not the link to add a new item inside the qualification (we hide it in case of the course-embedded tool where we have only one calification per course or session)
+     * @param boolean Whether to show or not the link to add a new qualification
+     * (we hide it in case of the course-embedded tool where we have only one
+     * calification per course or session)
+     * @param boolean Whether to show or not the link to add a new item inside
+     * the qualification (we hide it in case of the course-embedded tool
+     * where we have only one calification per course or session)
      * @return void Everything is printed on screen upon closing
 	 */
-	static function display_header_gradebook($catobj, $showtree, $selectcat, $is_course_admin, $is_platform_admin, $simple_search_form, $show_add_qualification = true, $show_add_link = true) {
+    static function display_header_gradebook(
+        $catobj,
+        $showtree,
+        $selectcat,
+        $is_course_admin,
+        $is_platform_admin,
+        $simple_search_form,
+        $show_add_qualification = true,
+        $show_add_link = true
+    ) {
 		//student
 		$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
 		$objcat = new Category();
@@ -369,6 +389,7 @@ class DisplayGradebook
 		$message_resource = $objcat->show_message_resource_delete($course_id);
 
         $grade_model_id = $catobj->get_grade_model_id();
+        $header = null;
 
         //@todo move these in a function
         $sum_categories_weight_array = array();
@@ -390,22 +411,28 @@ class DisplayGradebook
 			$scoredisplay = ScoreDisplay :: instance();
 
 			// generating the total score for a course
+            /*if (count($categories) > 0) {
+                foreach ($categories as $category) {
+                    $allevals = $category->get_evaluations($user_id, true);
+                    $alllinks = $category->get_links($user_id, true);
+                    $catEvalsLinks = array_merge($allevals, $alllinks);
+                }
+            }*/
 			$allevals= $catcourse[0]->get_evaluations($user_id,true);
 			$alllinks= $catcourse[0]->get_links($user_id,true);
-			$evals_links = array_merge($allevals, $alllinks);
 
-			$item_value =0;
-			$item_total = 0;
-            $item_total_value = 0;
+            $allEvalsLinks = array_merge($allevals, $alllinks);
 
-			for ($count=0; $count < count($evals_links); $count++) {
-				$item           = $evals_links[$count];
+            $item_value_total = 0;
+            $scoreinfo = null;
+
+            for ($count = 0; $count < count($allEvalsLinks); $count++) {
+                $item = $allEvalsLinks[$count];
 				$score          = $item->calc_score($user_id);
                 $divide			= ( ($score[1])==0 ) ? 1 : $score[1];
 
-                $sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
                 //$item_value     = $score[0]/$divide;
-                $item_value     = $score[0]/$divide*$item->get_weight()*$sub_cat_percentage/$main_weight;
+                $item_value = $score[0] / $divide * $item->get_weight();
                 $item_value_total +=$item_value;
 			}
             $item_total = $main_weight;
@@ -433,6 +460,7 @@ class DisplayGradebook
 			$tree= $cats[0]->get_tree();
 			unset ($cats);
 
+            $line = null;
 			foreach ($tree as $cat) {
 				for ($i= 0; $i < $cat[2]; $i++) {
 					$line .= '&mdash;';

+ 27 - 18
main/gradebook/lib/fe/evalform.class.php

@@ -90,7 +90,8 @@ class EvalForm extends FormValidator
     /**
      * This form will build a form to add users to an evaluation
      */
-    protected function build_add_user_to_eval() {
+    protected function build_add_user_to_eval()
+    {
         $this->addElement('header', get_lang('ChooseUser'));
         $select= $this->addElement('select', 'firstLetterUser', get_lang('FirstLetter'), null, array(
                 'onchange'=> 'document.add_users_to_evaluation.submit()'
@@ -120,7 +121,8 @@ class EvalForm extends FormValidator
     /**
      * This function builds a form to edit all results in an evaluation
      */
-    protected function build_all_results_edit_form() {
+    protected function build_all_results_edit_form()
+    {
         //extra field for check on maxvalue
         $this->addElement('hidden', 'maxvalue', $this->evaluation_object->get_max());
         $this->addElement('hidden', 'minvalue', 0);
@@ -178,10 +180,7 @@ class EvalForm extends FormValidator
             $result = $result_and_user['result'];
 
             $renderer = &$this->defaultRenderer();
-            $this->add_textfield('score[' . $result->get_id() . ']',
-                $this->build_stud_label($user['user_id'], $user['username'], $user['lastname'], $user['firstname']),
-                false,
-                array ('class' => "span2",
+            $this->add_textfield('score[' . $result->get_id() . ']', $this->build_stud_label($user['user_id'], $user['username'], $user['lastname'], $user['firstname']), false, array('class' => "span2",
                        'maxlength' => 5));
 
             $this->addRule('score[' . $result->get_id() . ']', get_lang('OnlyNumbers'), 'numeric');
@@ -218,7 +217,8 @@ class EvalForm extends FormValidator
      * This function builds a form to move an item to another category
      *
      */
-    protected function build_move_form() {
+    protected function build_move_form()
+    {
         $renderer = & $this->defaultRenderer();
         $renderer->setElementTemplate('<span>{element}</span> ');
         $this->addElement('static', null, null, '"'.$this->evaluation_object->get_name().'" ');
@@ -237,7 +237,8 @@ class EvalForm extends FormValidator
     /**
      * Builds a result form containing inputs for all students with a given course_code
      */
-    protected function build_result_add_form() {
+    protected function build_result_add_form()
+    {
         $renderer =& $this->defaultRenderer();
         $renderer->setFormTemplate(
             '<form{attributes}>
@@ -326,7 +327,8 @@ class EvalForm extends FormValidator
     /**
      * Builds a form to edit a result
      */
-    protected function build_result_edit_form() {
+    protected function build_result_edit_form()
+    {
         $this->setDefaults(array (
                 'score' => $this->result_object->get_score(),
                 'maximum' => $this->evaluation_object->get_max()
@@ -365,7 +367,8 @@ class EvalForm extends FormValidator
     /**
      * Builds a form to add an evaluation
      */
-    protected function build_add_form() {
+    protected function build_add_form()
+    {
         $this->setDefaults(array (	'hid_user_id' => $this->evaluation_object->get_user_id(),
                                       'hid_category_id' => $this->evaluation_object->get_category_id(),
                                       'hid_course_code' => $this->evaluation_object->get_course_code(), 'created_at' => api_get_utc_datetime()));
@@ -381,7 +384,8 @@ class EvalForm extends FormValidator
     /**
      * Builds a form to edit an evaluation
      */
-    protected function build_editing_form() {
+    protected function build_editing_form()
+    {
         $parent_cat = Category :: load($this->evaluation_object->get_category_id());
         if ($parent_cat[0]->get_parent_id() == 0) {
             $weight_mask = $this->evaluation_object->get_weight();
@@ -412,10 +416,11 @@ class EvalForm extends FormValidator
     /**
      * Builds a basic form that is used in add and edit
      */
-    private function build_basic_form($edit= 0) {
+    private function build_basic_form($edit = 0)
+    {
         $form_title = get_lang('NewEvaluation');
 
-        if ($_GET['editeval']==1) {
+        if (!empty($_GET['editeval']) && $_GET['editeval'] == 1) {
             $form_title = get_lang('EditEvaluation');
         }
 
@@ -467,7 +472,7 @@ class EvalForm extends FormValidator
             }
         }
 
-        $this->add_textfield('weight_mask', array(get_lang('Weight'), null, ' [0 .. '.$all_categories[0]->get_weight().'] '), true, array (
+        $this->add_textfield('weight_mask', array(get_lang('Weight'), null, ' [0 .. <span id="max_weight">' . $all_categories[0]->get_weight() . '</span>] '), true, array(
                 'size' => '4',
                 'maxlength' => '5',
                 'class' => 'span1'
@@ -524,15 +529,18 @@ class EvalForm extends FormValidator
 
     }
 
-    function display() {
+    function display()
+    {
         parent :: display();
     }
 
-    function setDefaults($defaults= array(), $filter = null) {
+    function setDefaults($defaults = array(), $filter = null)
+    {
         parent :: setDefaults($defaults, $filter);
     }
 
-    private function build_stud_label ($id, $username,$lastname, $firstname) {
+    private function build_stud_label($id, $username, $lastname, $firstname)
+    {
         $opendocurl_start = '';
         $opendocurl_end = '';
         // evaluation's origin is a link
@@ -547,7 +555,8 @@ class EvalForm extends FormValidator
         return $opendocurl_start . api_get_person_name($firstname, $lastname) .' ('.$username.')'. $opendocurl_end;
     }
 
-    function sort_by_user ($item1, $item2) {
+    function sort_by_user($item1, $item2)
+    {
         $user1 = $item1['user'];
         $user2 = $item2['user'];
         if (api_sort_by_first_name()) {

+ 80 - 21
main/gradebook/lib/fe/flatviewtable.class.php

@@ -1,37 +1,55 @@
 <?php
 /* For licensing terms, see /license.txt */
-/**
- * Script
- * @package chamilo.gradebook
- */
-/**
- * Init
- */
 require_once dirname(__FILE__).'/../../../inc/global.inc.php';
 require_once dirname(__FILE__).'/../be.inc.php';
 set_time_limit(0);
 
 /**
+ * Class FlatViewTable
  * Table to display flat view (all evaluations and links for all students)
  * @author Stijn Konings
  * @author Bert Steppé  - (refactored, optimised)
  * @author Julio Montoya Armas - Gradebook Graphics
+ *
  * @package chamilo.gradebook
  */
 class FlatViewTable extends SortableTable
 {
+    public $datagen;
     private $selectcat;
-    public  $datagen;
     private $limit_enabled;
     private $offset;
+    private $mainCourseCategory;
 
     /**
-     * Constructor
+     * @param Category $selectcat
+     * @param array $users
+     * @param array $evals
+     * @param array $links
+     * @param bool $limit_enabled
+     * @param int $offset
+     * @param null $addparams
+     * @param Category $mainCourseCategory
      */
-    function FlatViewTable ($selectcat, $users= array (), $evals= array (), $links= array (), $limit_enabled = false, $offset = 0, $addparams = null) {
+    public function FlatViewTable(
+        $selectcat,
+        $users = array(),
+        $evals = array(),
+        $links = array(),
+        $limit_enabled = false,
+        $offset = 0,
+        $addparams = null,
+        $mainCourseCategory = null
+    ) {
         parent :: __construct ('flatviewlist', null, null, (api_is_western_name_order() xor api_sort_by_first_name()) ? 1 : 0);
         $this->selectcat = $selectcat;
-        $this->datagen = new FlatViewDataGenerator($users, $evals, $links, array('only_subcat'=>$this->selectcat->get_id()));
+        $this->datagen = new FlatViewDataGenerator(
+            $users,
+            $evals,
+            $links,
+            array('only_subcat' => $this->selectcat->get_id()),
+            $mainCourseCategory
+        );
                 
         $this->limit_enabled = $limit_enabled;
         $this->offset = $offset;
@@ -41,12 +59,30 @@ class FlatViewTable extends SortableTable
         
         // step 2: generate rows: students
         $this->datagen->category = $this->selectcat;
+        $this->mainCourseCategory = $mainCourseCategory;
+    }
+
+    /**
+     * @param bool $value
+     */
+    public function setLimitEnabled($value)
+    {
+       $this->limit_enabled = (bool) $value;
+    }
+
+    /**
+     * @return Category
+     */
+    public function getMainCourseCategory()
+    {
+        return $this->mainCourseCategory;
     }
 
     /**
      * Display the graph of the total results of all students
      * */
-    function display_graph() {
+    public function display_graph()
+    {
         include_once api_get_path(LIBRARY_PATH).'pchart/pData.class.php';
         include_once api_get_path(LIBRARY_PATH).'pchart/pChart.class.php';
         include_once api_get_path(LIBRARY_PATH).'pchart/pCache.class.php';
@@ -162,7 +198,11 @@ class FlatViewTable extends SortableTable
         return api_get_path(WEB_ARCHIVE_PATH).$img_file;
     }
 
-    function display_graph_by_resource() {
+    /**
+     *
+     */
+    public function display_graph_by_resource()
+    {
         require_once api_get_path(LIBRARY_PATH).'pchart/pData.class.php';
         require_once api_get_path(LIBRARY_PATH).'pchart/pChart.class.php';
         require_once api_get_path(LIBRARY_PATH).'pchart/pCache.class.php';
@@ -182,7 +222,7 @@ class FlatViewTable extends SortableTable
             
             if (is_array($customdisplays) && count(($customdisplays))) {
                 
-                $user_results = $this->datagen->get_data_to_graph2();                
+                $user_results = $this->datagen->get_data_to_graph2(false);
                 $pre_result = $new_result = array();
                 $DataSet = new pData();
                 //filling the Dataset
@@ -295,10 +335,14 @@ class FlatViewTable extends SortableTable
                             
                             //Setting max height by default see #3296
                             if (!empty($max)) {
-                                $Test->setFixedScale(0, $max);    
+                                if (is_int($max)) {
+                                    $Test->setFixedScale(0, $max + 1, $max + 1);
+                                } else {
+                                	$Test->setFixedScale(0, $max);    
+                            	}
                             }
                             
-                            $Test->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(), SCALE_ADDALLSTART0, 150,150,150, TRUE, 0, 0, FALSE);
+                            $Test->drawScale($DataSet->GetData(), $DataSet->GetDataDescription(), SCALE_ADDALLSTART0, 150, 150, 150, TRUE, 0, 1, FALSE);
 
                             //background grid
                             $Test->drawGrid(4, TRUE,230,230,230,50);
@@ -308,6 +352,7 @@ class FlatViewTable extends SortableTable
                             //$Test->drawTreshold(0,143,55,72,TRUE,TRUE);
 
                             // Draw the bar graph
+                            $Test->setFontProperties(api_get_path(LIBRARY_PATH) . "pchart/fonts/tahoma.ttf", 11);
                             $Test->drawBarGraph($DataSet->GetData(),$DataSet->GetDataDescription(),TRUE);
 
                             //Set legend properties: width, height and text color and font
@@ -405,14 +450,16 @@ class FlatViewTable extends SortableTable
     /**
      * Function used by SortableTable to get total number of items in the table
      */
-    function get_total_number_of_items() {
+    public function get_total_number_of_items()
+    {
         return $this->datagen->get_total_users_count();
     }
 
     /**
      * Function used by SortableTable to generate the data to display
      */
-    function get_table_data ($from = 1, $per_page = null, $column = null, $direction = null, $sort = null) {
+    public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null)
+    {
         $is_western_name_order = api_is_western_name_order();
 
         // create page navigation if needed
@@ -422,8 +469,8 @@ class FlatViewTable extends SortableTable
         } else {
             $selectlimit = $totalitems;
         }
+        $header = null;
         if ($this->limit_enabled && $totalitems > LIMIT) {
-              $calcprevious = LIMIT;
             $header .= '<table style="width: 100%; text-align: right; margin-left: auto; margin-right: auto;" border="0" cellpadding="2">'
                         .'<tbody>'
                         .'<tr>';
@@ -490,7 +537,13 @@ class FlatViewTable extends SortableTable
             $column++;
         }
 
-        $data_array = $this->datagen->get_data($users_sorting, $from, $this->per_page, $this->offset, $selectlimit);
+        $data_array = $this->datagen->get_data(
+            $users_sorting,
+            $from,
+            $this->per_page,
+            $this->offset,
+            $selectlimit
+        );
 
         $table_data = array();
         foreach ($data_array as $user_row) {
@@ -517,7 +570,13 @@ class FlatViewTable extends SortableTable
 
     // Other functions
 
-    private function build_name_link ($user_id, $name) {
+    /**
+     * @param $user_id
+     * @param $name
+     * @return string
+     */
+    private function build_name_link($user_id, $name)
+    {
         return '<a href="user_stats.php?userid='.$user_id.'&selectcat='.$this->selectcat->get_id().'">'.$name.'</a>';
     }
 }

+ 96 - 35
main/gradebook/lib/fe/gradebooktable.class.php

@@ -1,23 +1,18 @@
 <?php
 /* For licensing terms, see license.txt */
-/**
- * Script
- * @package chamilo.gradebook
- */
-/**
- * Init
- */
 
 require_once dirname(__FILE__).'/../../../inc/global.inc.php';
 require_once dirname(__FILE__).'/../be.inc.php';
 
 /**
+ * GradebookTable Class
  * Table to display categories, evaluations and links
  * @author Stijn Konings
  * @author Bert Steppé (refactored, optimised)
  * @package chamilo.gradebook
  */
-class GradebookTable extends SortableTable {
+class GradebookTable extends SortableTable
+{
 
 	private $currentcat;
 	private $datagen;
@@ -27,7 +22,8 @@ class GradebookTable extends SortableTable {
 	/**
 	 * Constructor
 	 */
-    function GradebookTable ($currentcat, $cats = array(), $evals = array(), $links = array(), $addparams = null) {
+    public function GradebookTable($currentcat, $cats = array(), $evals = array(), $links = array(), $addparams = null)
+    {
   		//$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
     	parent :: __construct ('gradebooklist', null, null, (api_is_allowed_to_edit()?1:0));
 		$this->evals_links = array_merge($evals, $links);
@@ -50,7 +46,12 @@ class GradebookTable extends SortableTable {
         $this->set_header($column++, get_lang('Description'), false);
 
 		if (api_is_allowed_to_edit(null, true)) {
-			$this->set_header($column++, get_lang('Weight'),'','width="100px"');
+            $this->set_header(
+                $column++,
+                get_lang('Weight'),
+                '',
+                'width="100px"'
+            );
 		} else {
 			$this->set_header($column++, get_lang('Weight'), false);
 			$this->set_header($column++, get_lang('Result'), false);
@@ -63,11 +64,6 @@ class GradebookTable extends SortableTable {
 
         $this->odd_even_rows_enabled = false;
 
-		/*if (api_is_allowed_to_edit(null, true)) {
-			//$this->set_header($column++, get_lang('CreationDate'),true, 'width="100px"');
-		} elseif (($status<>1)  && !api_is_allowed_to_edit() && (!isset($_GET['selectcat']) || $_GET['selectcat']==0)) {
-			//$this->set_header($column++, get_lang('Date'),true, 'width="100px"');
-		}*/
 
 		//admins get an edit column
 		if (api_is_allowed_to_edit(null, true)) {
@@ -81,7 +77,6 @@ class GradebookTable extends SortableTable {
 		} else {
 	 	    if (empty($_GET['selectcat']) &&  !api_is_allowed_to_edit()) {
 			    $this->set_header($column++, get_lang('Certificates'),false);
-	 	    } else {
 	 	    	//$evals_links = array_merge($evals, $links);
 	 	    	//if (count($evals_links)>0) {
              	    //$this->set_header($column++, get_lang('Results'), false);
@@ -90,21 +85,34 @@ class GradebookTable extends SortableTable {
 		}
     }
 
-    function get_data() {
+    /**
+     * @return GradebookDataGenerator
+     */
+    public function get_data()
+    {
         return $this->datagen;
     }
 
 	/**
 	 * Function used by SortableTable to get total number of items in the table
+     * @return int
 	 */
-	function get_total_number_of_items() {
+    public function get_total_number_of_items()
+    {
 		return $this->datagen->get_total_items_count();
 	}
 
     /**
      * Function used by SortableTable to generate the data to display
+     * @param int $from
+     * @param int $per_page
+     * @param int $column
+     * @param string $direction
+     * @param int $sort
+     * @return array|mixed
      */
-    function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null) {
+    public function get_table_data($from = 1, $per_page = null, $column = null, $direction = null, $sort = null)
+    {
 
         //variables load in index.php
         global $my_score_in_gradebook, $certificate_min_score;
@@ -201,7 +209,15 @@ class GradebookTable extends SortableTable {
             //$row[] = $invisibility_span_open .Display::tag('h4', $data['3'] .' / '.$this->currentcat->get_weight()).$invisibility_span_close;
             //$average = $data['3']/$this->currentcat->get_weight()*100;
 
-            $average = $scoredisplay->display_score(array($data['3'], $this->currentcat->get_weight()), SCORE_SIMPLE, SCORE_BOTH, true);
+            $average = $scoredisplay->display_score(
+                array(
+                    $data['3'],
+                    $this->currentcat->get_weight()
+                ),
+                SCORE_SIMPLE,
+                SCORE_BOTH,
+                true
+            );
 
             if (api_is_allowed_to_edit(null, true)) {
                 $row[] = $invisibility_span_open .Display::tag('h4', $average).$invisibility_span_close;
@@ -269,6 +285,7 @@ class GradebookTable extends SortableTable {
 
                 $cats = Category :: load ($parent_id, null, null, null, null, null);
 
+                if (isset($cats[0])) {
                 $allcat  = $cats[0]->get_subcategories($stud_id, $course_code, $session_id);
                 $alleval = $cats[0]->get_evaluations($stud_id);
                 $alllink = $cats[0]->get_links($stud_id);
@@ -283,7 +300,6 @@ class GradebookTable extends SortableTable {
                 foreach ($data_array as $data) {
                     $row  = array();
                     $item = $data[0];
-                    $id   = $item->get_id();
 
                     //if the item is invisible, wrap it in a span with class invisible
                     $invisibility_span_open  = (api_is_allowed_to_edit() && $item->is_visible() == '0') ? '<span class="invisible">' : '';
@@ -306,8 +322,6 @@ class GradebookTable extends SortableTable {
 
                     //Weight
                     //$weight = $data[3]/$category_weight*$main_cat[0]->get_weight();
-                    /*$weight = $category_weight * $data[3] / $main_cat[0]->get_weight();
-                    $weight = $main_cat[0]->get_weight()*$weight/$category_weight;*/
 
                     $weight = $data[3];
 
@@ -315,7 +329,7 @@ class GradebookTable extends SortableTable {
 
                     $total_weight += $weight;
 
-                    $row[] = $invisibility_span_open.$weight.$extra.$invisibility_span_close;
+                        $row[] = $invisibility_span_open.$weight.$invisibility_span_close;
 
                     if (api_is_allowed_to_edit(null, true)) {
                         //$weight_total_links += intval($data[3]);
@@ -344,6 +358,7 @@ class GradebookTable extends SortableTable {
                             if (!is_null($value_data)) {
                                 $score = $item->calc_score(api_get_user_id());
                                 $new_score = $data[3]* $score[0] / $score[1];
+                                    $new_score = floatval(number_format($new_score, api_get_setting('gradebook_number_decimals')));
                                 $row[] = Display::tip($new_score, $data[4]);
                             }
                         }
@@ -364,15 +379,26 @@ class GradebookTable extends SortableTable {
                             $label = null;
                             $total = score_badges(array($total_weight.' / '.$category_weight, '100'));
                         } else {
-                            $label = Display::return_icon('warning.png', sprintf(get_lang('TotalWeightMustBeX'), $category_weight) );
+                                $label = Display::return_icon(
+                                    'warning.png',
+                                    sprintf(get_lang('TotalWeightMustBeX'), $category_weight)
+                                );
                             $total = Display::badge($total_weight.' / '.$category_weight, 'warning');
                         }
-                        $row = array(null, null, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<h5>".get_lang('SubTotal').'</h5>',null, $total.' '.$label, 'child_of' =>$parent_id);
+                            $row = array(
+                                null,
+                                null,
+                                "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<h5>".get_lang('SubTotal').'</h5>',
+                                null,
+                                $total.' '.$label,
+                                'child_of' => $parent_id
+                            );
                         $sortable_data[] = $row;
                     }
                 }
             }
         } //end looping categories
+        } //end looping categories
 
         if (api_is_allowed_to_edit()) {
             if (count($main_cat) > 1) {
@@ -399,7 +425,10 @@ class GradebookTable extends SortableTable {
                 $course_code = $this->build_course_code($category[0]);
                 $weight_total_links  = round($weight_total_links);
 
-                if ($weight_total_links > $weight_category || $weight_total_links < $weight_category || $weight_total_links > $weight_category) {
+                if ($weight_total_links > $weight_category ||
+                    $weight_total_links < $weight_category ||
+                    $weight_total_links > $weight_category
+                ) {
                     $warning_message = sprintf(get_lang('TotalWeightMustBeX'), $weight_category);
                     $modify_icons  = '<a class="right_link" href="gradebook_edit_cat.php?editcat='.$id_cat.'&cidReq='.$course_code.'">'.Display::return_icon('edit.png', $warning_message, array(), ICON_SIZE_SMALL).'</a>';
                     $warning_message .= $modify_icons;
@@ -461,19 +490,39 @@ class GradebookTable extends SortableTable {
 
     // Other functions
 
-    private function build_certificate_min_score ($item) {
+    /**
+     * @param $item
+     * @return mixed
+     */
+    private function build_certificate_min_score ($item)
+    {
         return $item->get_certificate_min_score();
     }
 
-    private function build_weight ($item) {
+    /**
+     * @param $item
+     * @return mixed
+     */
+    private function build_weight($item)
+    {
         return $item->get_weight();
     }
 
-    private function build_course_code ($item) {
+    /**
+     * @param $item
+     * @return mixed
+     */
+    private function build_course_code ($item)
+    {
     	return $item->get_course_code();
     }
 
-    private function build_id_column ($item) {
+    /**
+     * @param $item
+     * @return string
+     */
+    private function build_id_column ($item)
+    {
 		switch ($item->get_item_type()) {
 			// category
 			case 'C' :
@@ -487,17 +536,24 @@ class GradebookTable extends SortableTable {
 		}
 	}
 
-	private function build_type_column ($item, $attributes = array()) {
+    /**
+     * @param $item
+     * @param array $attributes
+     * @return string
+     */
+    private function build_type_column ($item, $attributes = array())
+    {
 		return build_type_icon_tag($item->get_icon_name(), $attributes);
 	}
 
 	/**
-	 *
 	 * Generate name column
 	 * @param unknown_type $item
 	 * @return string
 	 */
-	private function build_name_link ($item) {
+	private function build_name_link ($item)
+    {
+        $view = isset($_GET['view']) ? Security::remove_XSS($_GET['view']) : null;
         //$session_id = api_get_session_id();
 		switch ($item->get_item_type()) {
 			// category
@@ -579,7 +635,12 @@ class GradebookTable extends SortableTable {
 		}
 	}
 
-	private function build_edit_column($item) {
+    /**
+     * @param $item
+     * @return null|string
+     */
+    private function build_edit_column($item)
+    {
 		switch ($item->get_item_type()) {
 			// category
 			case 'C' :

+ 15 - 3
main/gradebook/lib/fe/linkaddeditform.class.php

@@ -27,7 +27,14 @@ class LinkAddEditForm extends FormValidator
 	 * To add link, define category_object and link_type
 	 * To edit link, define link_object
 	 */
-    function LinkAddEditForm($form_type, $category_object, $link_type, $link_object, $form_name, $action = null) {
+    public function LinkAddEditForm(
+        $form_type,
+        $category_object,
+        $link_type,
+        $link_object,
+        $form_name,
+        $action = null
+    ) {
 		parent :: __construct($form_name, 'post', $action);
 
 		// set or create link object
@@ -91,11 +98,16 @@ class LinkAddEditForm extends FormValidator
             }
         }
 
-		$this->add_textfield('weight_mask', array(get_lang('Weight'), null, ' [0 .. '.$category_object[0]->get_weight().'] '), true, array (
+		$this->add_textfield(
+            'weight_mask',
+            array(get_lang('Weight'), null, ' [0 .. <span id="max_weight">'.$category_object[0]->get_weight().'</span>] '),
+            true,
+            array(
 			'size' => '4',
 			'maxlength' => '5',
             'class' => 'span1'
-		));
+		    )
+        );
 
         $this->addElement('hidden', 'weight');
 

+ 34 - 11
main/gradebook/lib/fe/linkform.class.php

@@ -69,29 +69,40 @@ class LinkForm extends FormValidator
    		$this->addElement('submit', null, get_lang('Ok'));
 	}
 
-	protected function build_create() {
+	protected function build_create()
+    {
 		$this->addElement('header', get_lang('MakeLink'));
 		$select = $this->addElement('select', 'select_link', get_lang('ChooseLink'), null, array('onchange' => 'document.create_link.submit()'));
 
-		$linktypes = LinkFactory :: get_all_types();
+		$linkTypes = LinkFactory::get_all_types();
 
 		$select->addoption('['.get_lang('ChooseLink').']', 0);
 
-		$cc = $this->category_object->get_course_code();
+		$courseCode = $this->category_object->get_course_code();
 
-		foreach ($linktypes as $linktype) {
-			$link = LinkFactory :: create ($linktype);
-			if (!empty($cc)) {
-				$link->set_course_code($cc);
-			} elseif(!empty($_GET['course_code'])) {
-				$link->set_course_code(Database::escape_string($_GET['course_code']));
+		foreach ($linkTypes as $linkType) {
+            // The hot potatoe link will be added "inside" the exercise option.
+            if ($linkType == LINK_HOTPOTATOES) {
+                continue;
 			}
+            $link = $this->createLink($linkType, $courseCode);
 			// disable this element if the link works with a dropdownlist
 			// and if there are no links left
 			if (!$link->needs_name_and_description() && count($link->get_all_links()) == '0') {
-				$select->addoption($link->get_type_name(), $linktype, 'disabled');
+				$select->addoption($link->get_type_name(), $linkType, 'disabled');
 			} else {
-				$select->addoption($link->get_type_name(), $linktype);
+                if ($link->get_type() == LINK_EXERCISE) {
+                    // Adding exercise
+				    $select->addoption($link->get_type_name(), $linkType);
+                    // Adding hot potatoes
+                    $linkHot = $this->createLink(LINK_HOTPOTATOES, $courseCode);
+                    $select->addoption(
+                        '&nbsp;&nbsp;&nbsp;'.$linkHot->get_type_name(),
+                        LINK_HOTPOTATOES
+                    );
+                } else {
+                    $select->addoption($link->get_type_name(), $linkType);
+                }
 			}
 		}
 
@@ -99,4 +110,16 @@ class LinkForm extends FormValidator
 			$this->setDefaults(array('select_link' => $this->extra));
 		}
 	}
+    /**
+     * @param $link
+     * @param $courseCode
+     * @return AttendanceLink|DropboxLink|ExerciseLink|ForumThreadLink|LearnpathLink|null|StudentPublicationLink|SurveyLink
+     */
+    private function createLink($link, $courseCode)
+    {
+        $link = LinkFactory::create($link);
+        if (!empty($courseCode)) {
+            $link->set_course_code($courseCode);
+        } elseif(!empty($_GET['course_code'])) {
+            $link->set_course_code(Database::escape_string($_GET['course_code']));
 }

+ 1 - 1
main/gradebook/lib/fe/resulttable.class.php

@@ -131,7 +131,7 @@ class ResultTable extends SortableTable
 				$row[] = $item['firstname'];
 			}
 
-			$row[] =  Display::bar_progress($item['percentage_score'], false, $item['score'], true);
+			$row[] =  Display::bar_progress($item['percentage_score'], false, $item['score']);
             //$row[] =  Display::bar_progress($item['percentage_score'], true);
 			if ($scoredisplay->is_custom()) {
 				$row[] = $item['display'];

+ 279 - 75
main/gradebook/lib/flatview_data_generator.class.php

@@ -1,13 +1,11 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
+ * Class FlatViewDataGenerator
  * Class to select, sort and transform object data into array data,
  * used for the teacher's flat view
  * @author Bert Steppé
- * @package chamilo.gradebook
- */
-/**
- * Class
+ *
  * @package chamilo.gradebook
  */
 class FlatViewDataGenerator
@@ -24,40 +22,58 @@ class FlatViewDataGenerator
 	private $evals_links;	
     public $params;
 	public  $category = array();
+    private $mainCourseCategory;
 
 	/**
 	 * Constructor
 	 */
-    public function FlatViewDataGenerator ($users = array(), $evals = array(), $links = array(), $params = array()) {
+    public function FlatViewDataGenerator(
+        $users = array(),
+        $evals = array(),
+        $links = array(),
+        $params = array(),
+        $mainCourseCategory = null
+    ) {
 		$this->users = (isset($users) ? $users : array());
 		$this->evals = (isset($evals) ? $evals : array());
 		$this->links = (isset($links) ? $links : array());
 		$this->evals_links = array_merge($this->evals, $this->links);
         $this->params = $params;
+        $this->mainCourseCategory = $mainCourseCategory;
     }
 
 	/**
+     * @return Category
+     */
+    public function getMainCourseCategory()
+    {
+        return $this->mainCourseCategory;
+    }
+    /**
 	 * Get total number of users (rows)
 	 */
-	public function get_total_users_count() {
+    public function get_total_users_count()
+    {
 		return count($this->users);
 	}
 
 	/**
 	 * Get total number of evaluations/links (columns) (the 2 users columns not included)
 	 */
-	public function get_total_items_count() {
+    public function get_total_items_count()
+    {
 		return count($this->evals_links);
 	}
 
 	/**
 	 * Get array containing column header names (incl user columns)
-     * @param int Start item offset
-     * @param int Number of items to get
-     * @param bool whether to show the details or not
+     * @param int $items_start Start item offset
+     * @param int $items_count Number of items to get
+     * @param bool $show_detail whether to show the details or not
      * @return array List of headers 
 	 */
-	public function get_header_names($items_start = 0, $items_count = null , $show_detail = false) {
+    public function get_header_names($items_start = 0, $items_count = null, $show_detail = false)
+    {
 		$headers = array();        
                 
         if (isset($this->params['show_official_code']) && $this->params['show_official_code']) {
@@ -84,7 +100,9 @@ class FlatViewDataGenerator
         
         $parent_id = $this->category->get_parent_id();
         
-        if ($parent_id == 0 or $this->params['only_subcat'] == $this->category->get_id()) {
+        if ($parent_id == 0 or
+            $this->params['only_subcat'] == $this->category->get_id()
+        ) {
             $main_weight  = $this->category->get_weight();
             $grade_model_id = $this->category->get_grade_model_id();
         } else {
@@ -100,6 +118,12 @@ class FlatViewDataGenerator
 		        
 		//@todo move these in a function
 		$sum_categories_weight_array = array();
+        $mainCategoryId = null;
+        $mainCourseCategory = $this->getMainCourseCategory();
+
+        if (!empty($mainCourseCategory)) {
+            $mainCategoryId = $mainCourseCategory->get_id();
+        }
 		if (isset($this->category) && !empty($this->category)) {
 			$categories = Category::load(null, null, null, $this->category->get_id());            
 			if (!empty($categories)) {
@@ -116,7 +140,13 @@ class FlatViewDataGenerator
         $course_code 	= api_get_course_id();            
         $session_id		= api_get_session_id();
 
-        $allcat  = $this->category->get_subcategories(null, $course_code, $session_id, 'ORDER BY id');
+        $allcat = $this->category->get_subcategories(
+            null,
+            $course_code,
+            $session_id,
+            'ORDER BY id'
+        );
+        $evaluationsAdded = array();
                     
         if ($parent_id == 0 && !empty($allcat)) {             
             
@@ -124,25 +154,48 @@ class FlatViewDataGenerator
             foreach ($allcat as $sub_cat) {
                 $sub_cat_weight = round(100*$sub_cat->get_weight()/$main_weight,1);
                 $add_weight = " $sub_cat_weight %";
-                if (isset($this->params['export_pdf']) && $this->params['export_pdf']) {
+                /*if (isset($this->params['export_pdf']) && $this->params['export_pdf']) {
                    $add_weight = null;
-                }
-                $headers[] = Display::url($sub_cat->get_name(), api_get_self().'?selectcat='.$sub_cat->get_id()).$add_weight;                    
+                }*/
+                $headers[] = Display::url(
+                    $sub_cat->get_name(),
+                    api_get_self().'?selectcat='.$sub_cat->get_id()
+                ).$add_weight;
             }
         } else {
-            if (!isset($this->params['only_total_category']) || (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)) {
+            if (!isset($this->params['only_total_category']) ||
+                (isset($this->params['only_total_category']) &&
+                $this->params['only_total_category'] == false)
+            ) {
                 for ($count=0; ($count < $items_count ) && ($items_start + $count < count($this->evals_links)); $count++) {
                     $item = $this->evals_links[$count + $items_start];                    
                     $weight = round(100*$item->get_weight()/$main_weight,1);
                     $headers[] = $item->get_name().' '.$weight.' % ';                
+                    $evaluationsAdded[] = $item->get_id();
                 }
             }            
         }
+        if (!empty($mainCategoryId)) {
+            for ($count = 0; ($count < $items_count) && ($items_start + $count < count($this->evals_links)); $count++) {
+                /** @var AbstractLink $item */
+                $item = $this->evals_links[$count + $items_start];
+                if ($mainCategoryId == $item->get_category_id() && !in_array($item->get_id(), $evaluationsAdded)) {
+                    $weight = round(100 * $item->get_weight() / $main_weight, 1);
+                    $headers[] = $item->get_name() . ' ' . $weight . ' % ';
+                }
+            }
+        }
         $headers[] = api_strtoupper(get_lang('GradebookQualificationTotal'));
 		return $headers;
 	}
 	
-	function get_max_result_by_link($id) {						
+    /**
+     * @param int $id
+     *
+     * @return int
+     */
+    public function get_max_result_by_link($id)
+    {
 		$max = 0;
 		foreach ($this->users as $user) {
 			$item  = $this->evals_links [$id];					
@@ -157,7 +210,8 @@ class FlatViewDataGenerator
 	/**
 	 * Get array containing evaluation items
 	 */
-	public function get_evaluation_items($items_start = 0, $items_count = null) {
+    public function get_evaluation_items($items_start = 0, $items_count = null)
+    {
 		$headers = array();
 		if (!isset($items_count)) {
 			$items_count = count($this->evals_links) - $items_start;
@@ -177,9 +231,15 @@ class FlatViewDataGenerator
 	 * 2: user firstname
 	 * 3+: evaluation/link scores
 	 */
-	public function get_data ($users_sorting = 0, $users_start = 0, $users_count = null,
-							  $items_start = 0, $items_count = null,
-							  $ignore_score_color = false, $show_all = false) {
+    public function get_data(
+        $users_sorting = 0,
+        $users_start = 0,
+        $users_count = null,
+        $items_start = 0,
+        $items_count = null,
+        $ignore_score_color = false,
+        $show_all = false
+    ) {
 		
 		// do some checks on users/items counts, redefine if invalid values
 		if (!isset($users_count)) {
@@ -197,24 +257,24 @@ class FlatViewDataGenerator
         
 		// copy users to a new array that we will sort
 		// TODO - needed ?
-		$usertable = array ();
+        $userTable = array();
 		foreach ($this->users as $user) {
-			$usertable[] = $user;
+            $userTable[] = $user;
 		}
         
 		// sort users array
 		if ($users_sorting & self :: FVDG_SORT_LASTNAME) {
-			usort($usertable, array ('FlatViewDataGenerator','sort_by_last_name'));
+            usort($userTable, array ('FlatViewDataGenerator','sort_by_last_name'));
 		} elseif ($users_sorting & self :: FVDG_SORT_FIRSTNAME) {
-			usort($usertable, array ('FlatViewDataGenerator','sort_by_first_name'));
+            usort($userTable, array ('FlatViewDataGenerator','sort_by_first_name'));
 		}
 
 		if ($users_sorting & self :: FVDG_SORT_DESC) {
-			$usertable = array_reverse($usertable);
+            $userTable = array_reverse($userTable);
 		}
 
 		// select the requested users
-		$selected_users = array_slice($usertable, $users_start, $users_count);
+        $selected_users = array_slice($userTable, $users_start, $users_count);
         
 		// generate actual data array
 		$scoredisplay = ScoreDisplay :: instance();
@@ -226,6 +286,11 @@ class FlatViewDataGenerator
 		}
 		//@todo move these in a function
 		$sum_categories_weight_array = array();     
+        $mainCategoryId = null;
+        $mainCourseCategory = $this->getMainCourseCategory();
+        if (!empty($mainCourseCategory)) {
+            $mainCategoryId = $mainCourseCategory->get_id();
+        }
         
         if (isset($this->category) && !empty($this->category)) {            
             $categories = Category::load(null, null, null, $this->category->get_id());
@@ -311,6 +376,7 @@ class FlatViewDataGenerator
             $session_id		= api_get_session_id();
             $allcat         = $this->category->get_subcategories(null, $course_code, $session_id, 'ORDER BY id');
 
+            $evaluationsAdded = array();
             if ($parent_id == 0 && !empty($allcat)) {
                                                 
                 foreach ($allcat as $sub_cat) {
@@ -344,7 +410,10 @@ class FlatViewDataGenerator
                         $temp_score = Display::tip($temp_score, $real_score);
                     }                    
                     
-                    if (!isset($this->params['only_total_category']) || (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)) {
+                    if (!isset($this->params['only_total_category']) ||
+                        (isset($this->params['only_total_category']) &&
+                        $this->params['only_total_category'] == false)
+                    ) {
                         if (!$show_all) {
                            $row[] = $temp_score.' ';   
                         } else {                 
@@ -357,8 +426,100 @@ class FlatViewDataGenerator
                     //$item_total = $main_weight;
                 }
             } else  {
+                $result = $this->parseEvaluations(
+                    $user_id,
+                    $sum_categories_weight_array,
+                    $items_count,
+                    $items_start,
+                    $show_all,
+                    $row
+                );
+
+                $item_total += $result['item_total'];
+                $item_value_total += $result['item_value_total'];
+                $evaluationsAdded = $result['evaluations_added'];
+                $item_total = $main_weight;
+            }
+
+            // All evaluations
+            $result = $this->parseEvaluations(
+                $user_id,
+                $sum_categories_weight_array,
+                $items_count,
+                $items_start,
+                $show_all,
+                $row,
+                $mainCategoryId,
+                $evaluationsAdded
+            );
+
+            $item_total += $result['item_total'];
+            $item_value_total += $result['item_value_total'];
+
+            $total_score = array($item_value_total, $item_total);
+
+            if (!$show_all) {
+                if ($export_to_pdf) {
+                    $row['total'] = $scoredisplay->display_score($total_score);
+                } else {
+                    $row[] = $scoredisplay->display_score($total_score);
+                }
+            } else {
+                if ($export_to_pdf) {
+                    $row['total'] = $scoredisplay->display_score($total_score, SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS);
+                } else {
+                    $row[] = $scoredisplay->display_score($total_score, SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS);
+                }
+            }
+            unset($score);
+            $data[] = $row;
+        }
+
+        return $data;
+    }
+
+    /**
+     * Parse evaluations
+     *
+     * @param int $user_id
+     * @param array $sum_categories_weight_array
+     * @param int $items_count
+     * @param int $items_start
+     * @param int $show_all
+     * @param int $parentCategoryIdFilter filter by category id if set
+     * @return array
+     */
+    public function parseEvaluations(
+        $user_id,
+        $sum_categories_weight_array,
+        $items_count,
+        $items_start,
+        $show_all,
+        & $row,
+        $parentCategoryIdFilter = null,
+        $evaluationsAlreadyAdded = array()
+    ) {
+        // Generate actual data array
+        $scoredisplay = ScoreDisplay :: instance();
+        $item_total = 0;
+        $item_value_total = 0;
+
+        $evaluationsAdded = array();
                 for ($count=0; ($count < $items_count ) && ($items_start + $count < count($this->evals_links)); $count++) {
                     $item  			= $this->evals_links[$count + $items_start];                    
+            if (!empty($evaluationsAlreadyAdded)) {
+                if (in_array($item->get_id(), $evaluationsAlreadyAdded)) {
+                    continue;
+                }
+            }
+
+            if (!empty($parentCategoryIdFilter)) {
+                if ($item->get_category_id() != $parentCategoryIdFilter) {
+                    continue;
+                }
+            }
+
+            $evaluationsAdded[] = $item->get_id();
                     $score 			= $item->calc_score($user_id);
                     $real_score     = $score;
                     $divide			= ( ($score[1])==0 ) ? 1 : $score[1];
@@ -369,17 +530,18 @@ class FlatViewDataGenerator
                     $item_value     = $score[0]/$divide;
                     
                     //Fixing total when using one or multiple gradebooks 
+            if (empty($parentCategoryIdFilter)) {
                     if ($this->category->get_parent_id() == 0 ) {                        
                         $item_value     = $score[0]/$divide*$item->get_weight();
                     } else {
                         $item_value     = $item_value*$item->get_weight();                         
                     }
+            } else {
+                $item_value = $score[0] / $divide * $item->get_weight();
+            }
                     
                     $item_total     += $item->get_weight();                    
-                    /*
                     $complete_score = $scoredisplay->display_score($score, SCORE_DIV_PERCENT, SCORE_ONLY_SCORE);                    
-                    $temp_score  = $scoredisplay->display_score(array($item_value, null), SCORE_DIV_SIMPLE_WITH_CUSTOM);                    
-                    $temp_score = Display::tip($temp_score, $complete_score);*/
                     
                     //if (true) {
                     if (api_get_setting('gradebook_show_percentage_in_reports') == 'false') {
@@ -391,10 +553,21 @@ class FlatViewDataGenerator
                         $temp_score = Display::tip($temp_score, $complete_score);
                     }
                     
-                    if (!isset($this->params['only_total_category']) || (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)) {
+            if (!isset($this->params['only_total_category']) ||
+                (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)
+            ) {
                         if (!$show_all) {                            
-                            if (in_array($item->get_type() , array(LINK_EXERCISE, LINK_DROPBOX, LINK_STUDENTPUBLICATION, 
-                                                                   LINK_LEARNPATH, LINK_FORUM_THREAD,  LINK_ATTENDANCE,LINK_SURVEY))) {
+                    if (in_array($item->get_type(), array(
+                            LINK_EXERCISE,
+                            LINK_DROPBOX,
+                            LINK_STUDENTPUBLICATION,
+                            LINK_LEARNPATH,
+                            LINK_FORUM_THREAD,
+                            LINK_ATTENDANCE,
+                            LINK_SURVEY,
+                            LINK_HOTPOTATOES)
+                    )
+                    ) {
                                 if (!empty($score[0])) {
                                    $row[] = $temp_score.' ';                                        
                                 } else {
@@ -409,37 +582,24 @@ class FlatViewDataGenerator
                     }                    
                     $item_value_total +=$item_value;
                 }
-                $item_total = $main_weight;
-            }            
-			$total_score = array($item_value_total, $item_total);            
             
-			if (!$show_all) {
-                if ($export_to_pdf) {
-                    $row['total'] = $scoredisplay->display_score($total_score);
-                } else {
-                    $row[] = $scoredisplay->display_score($total_score);
-                }
-			} else {
-                if ($export_to_pdf) {
-                    $row['total'] = $scoredisplay->display_score($total_score, SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS);
-                } else {
-                    $row[] = $scoredisplay->display_score($total_score, SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS);
-                }
-			}
-			unset($score); 
-            //var_dump($row);exit;
-			$data[] = $row;
-		}        
-		return $data;
+        return array(
+            'item_total' => $item_total,
+            'item_value_total' => $item_value_total,
+            'evaluations_added' => $evaluationsAdded
+        );
 	}
 
 	/**
 	 * Get actual array data evaluation/link scores
 	 */
-	public function get_evaluation_sumary_results ($session_id = null) {
+    public function get_evaluation_sumary_results ($session_id = null)
+    {
 
 		$usertable = array ();
-		foreach ($this->users as $user) { $usertable[] = $user; }
+        foreach ($this->users as $user) {
+            $usertable[] = $user;
+        }
 		$selected_users = $usertable;
 
 		// generate actual data array for all selected users
@@ -483,7 +643,11 @@ class FlatViewDataGenerator
 		return $result;
 	}
 
-	public function get_data_to_graph () {
+    /**
+     * @return array
+     */
+    public function get_data_to_graph()
+    {
 		// do some checks on users/items counts, redefine if invalid values
 		$usertable = array ();
 		foreach ($this->users as $user) {
@@ -523,7 +687,13 @@ class FlatViewDataGenerator
 		return $data;
 	}
 
-	public function get_data_to_graph2 () {
+    /**
+     * This is a function to show the generated data
+     * @param bool $displayWarning
+     * @return array
+     */
+    public function get_data_to_graph2($displayWarning = true)
+    {
 		// do some checks on users/items counts, redefine if invalid values
 		$usertable = array ();
 		foreach ($this->users as $user) {
@@ -542,21 +712,53 @@ class FlatViewDataGenerator
 			$row[] = $user[0];	// user id
 			$item_value=0;
 			$item_total=0;
+            $final_score = 0;
+            $item_value_total = 0;
+            $convert_using_the_global_weight = true;
 
-			for ($count=0;$count < count($this->evals_links); $count++) {
-				$item = $this->evals_links [$count];
-				$score = $item->calc_score($user[0]);
-				$divide=( ($score[1])==0 ) ? 1 : $score[1];
-				$item_value+= $score[0]/$divide*$item->get_weight();
-				$item_total+=$item->get_weight();
-				$score_denom=($score[1]==0) ? 1 : $score[1];
-				$score_final = ($score[0] / $score_denom) * 100;
-				$row[] = array ($score_final, trim($scoredisplay->display_score($score, SCORE_CUSTOM,null, true)));
+            $course_code     = api_get_course_id();
+            $session_id        = api_get_session_id();
+            $allcat         = $this->category->get_subcategories(null, $course_code, $session_id, 'ORDER BY id');
 
-			}
-			$total_score=array($item_value,$item_total);
-			$score_final = ($item_value / $item_total) * 100;
-			$row[] =array ($score_final, trim($scoredisplay->display_score($total_score, SCORE_CUSTOM, null, true)));
+            if ($parent_id == 0 && !empty($allcat)) {
+
+                foreach ($allcat as $sub_cat) {
+                    $score             = $sub_cat->calc_score($user[0]);
+                    $real_score     = $score;
+                    $main_weight  = $this->category->get_weight();
+                    $divide            = ( ($score[1])==0 ) ? 1 : $score[1];
+
+                    $sub_cat_percentage = $sum_categories_weight_array[$sub_cat->get_id()];
+                    $item_value     = $score[0]/$divide*$main_weight;
+                    $item_total        += $sub_cat->get_weight();
+
+                    $row[] = array ($item_value, trim($scoredisplay->display_score($real_score, SCORE_CUSTOM,null, true)));
+                    $item_value_total += $item_value;
+                    $final_score += $score[0];
+                    //$final_score = ($final_score / $item_total) * 100;
+
+                }
+                $total_score = array($final_score, $item_total);
+                $row[] = array ($final_score, trim($scoredisplay->display_score($total_score, SCORE_CUSTOM, null, true)));
+            } else {
+				for ($count=0;$count < count($this->evals_links); $count++) {
+					$item = $this->evals_links [$count];
+					$score = $item->calc_score($user[0]);
+					$divide=( ($score[1])==0 ) ? 1 : $score[1];
+					$item_value+= $score[0]/$divide*$item->get_weight();
+					$item_total+=$item->get_weight();
+					$score_denom=($score[1]==0) ? 1 : $score[1];
+					$score_final = ($score[0] / $score_denom) * 100;
+					$row[] = array ($score_final, trim($scoredisplay->display_score($score, SCORE_CUSTOM,null, true)));
+
+				}
+				$total_score=array($item_value,$item_total);
+				$score_final = ($item_value / $item_total) * 100;
+	            if ($displayWarning) {
+	                Display::display_warning_message( Display::display_warning_message($total_score[1]));
+	            }
+				$row[] =array ($score_final, trim($scoredisplay->display_score($total_score, SCORE_CUSTOM, null, true)));
+            }
 
 			$data[] = $row;
 		}
@@ -564,11 +766,13 @@ class FlatViewDataGenerator
 	}
 	// Sort functions - used internally
 
-	function sort_by_last_name($item1, $item2) {
+    public function sort_by_last_name($item1, $item2)
+    {
 		return api_strcmp($item1[2], $item2[2]);
 	}
 
-	function sort_by_first_name($item1, $item2) {
+    public function sort_by_first_name($item1, $item2)
+    {
 		return api_strcmp($item1[3], $item2[3]);
 	}
 }

+ 44 - 18
main/gradebook/lib/gradebook_data_generator.class.php

@@ -1,10 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
- * Script
- * @package chamilo.gradebook
- */
-/**
+ * GradebookDataGenerator Class
  * Class to select, sort and transform object data into array data,
  * used for the general gradebook view
  * @author Bert Steppé
@@ -29,19 +26,38 @@ class GradebookDataGenerator
 	private $items;
 	private $evals_links;
 
-    function GradebookDataGenerator($cats = array(), $evals = array(), $links = array()) {
+    public function GradebookDataGenerator($cats = array(), $evals = array(), $links = array())
+    {
 		$allcats = (isset($cats) ? $cats : array());
 		$allevals = (isset($evals) ? $evals : array());
 		$alllinks = (isset($links) ? $links : array());
 		// merge categories, evaluations and links
-		$this->items = array_merge($allcats, $allevals, $alllinks);
-		$this->evals_links = array_merge($allevals, $alllinks);
+        $tabLinkToDisplay = $alllinks;
+        if (count($allcats) > 0) {
+            // get sub categories id
+            $tabCategories = array();
+            for ($i=0; $i < count($allcats); $i++) {
+                $tabCategories[] = $allcats[$i]->get_id();
+            }
+            // dont display links that belongs to a sub category
+            $tabLinkToDisplay = array();
+            for ($i=0; $i < count($alllinks); $i++) {
+                if (!in_array($alllinks[$i]->get_category_id(), $tabCategories)) {
+                    $tabLinkToDisplay[] = $alllinks[$i];
+                }
+            }
+        }
+
+        // merge categories, evaluations and links
+        $this->items = array_merge($allcats, $allevals, $tabLinkToDisplay);
+        $this->evals_links = array_merge($allevals, $tabLinkToDisplay);
     }
 
 	/**
 	 * Get total number of items (rows)
 	 */
-	public function get_total_items_count() {
+    public function get_total_items_count()
+    {
 		return count($this->items);
 	}
 
@@ -55,7 +71,8 @@ class GradebookDataGenerator
 	 * 4: date
 	 * 5: student's score (if student logged in)
 	 */
-	public function get_data($sorting = 0, $start = 0, $count = null, $ignore_score_color = false) {
+    public function get_data($sorting = 0, $start = 0, $count = null, $ignore_score_color = false)
+    {
 		//$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
 		// do some checks on count, redefine if invalid value
 		if (!isset($count)) {
@@ -120,7 +137,8 @@ class GradebookDataGenerator
 	 * @param object Item
      * @return string
 	 */
-	function get_certificate_link($item) {
+    public function get_certificate_link($item)
+    {
 		if (is_a($item, 'Category')) {
 			if($item->is_certificate_available(api_get_user_id())) {
 				$link = '<a href="'.Security::remove_XSS($_SESSION['gradebook_dest']).'?export_certificate=1&cat='.$item->get_id().'&user='.api_get_user_id().'">'.get_lang('Certificate').'</a>';
@@ -132,15 +150,18 @@ class GradebookDataGenerator
     // Sort functions
     // Make sure to only use functions as defined in the GradebookItem interface !
 
-	function sort_by_name($item1, $item2) {
+    public function sort_by_name($item1, $item2)
+    {
 		return api_strnatcmp($item1->get_name(), $item2->get_name());
 	}
 
-    function sort_by_id($item1, $item2) {
+    public function sort_by_id($item1, $item2)
+    {
         return api_strnatcmp($item1->get_id(), $item2->get_id());
     }
 
-	function sort_by_type($item1, $item2) {
+    public function sort_by_type($item1, $item2)
+    {
 		if ($item1->get_item_type() == $item2->get_item_type()) {
 			return $this->sort_by_name($item1,$item2);
 		} else {
@@ -148,7 +169,8 @@ class GradebookDataGenerator
 		}
 	}
 
-	function sort_by_description($item1, $item2) {
+    public function sort_by_description($item1, $item2)
+    {
 		$result = api_strcmp($item1->get_description(), $item2->get_description());
 		if ($result == 0) {
 			return $this->sort_by_name($item1,$item2);
@@ -156,7 +178,8 @@ class GradebookDataGenerator
 		return $result;
 	}
 
-	function sort_by_weight($item1, $item2) {
+    public function sort_by_weight($item1, $item2)
+    {
 		if ($item1->get_weight() == $item2->get_weight()) {
 			return $this->sort_by_name($item1,$item2);
 		} else {
@@ -164,7 +187,8 @@ class GradebookDataGenerator
 		}
 	}
 
-	function sort_by_date($item1, $item2) {
+    public function sort_by_date($item1, $item2)
+    {
 		if (is_int($item1->get_date())) {
 			$timestamp1 = $item1->get_date();
 		} else {
@@ -190,7 +214,8 @@ class GradebookDataGenerator
 	}
 
     //  Other functions
-	private function build_result_column($item, $ignore_score_color) {
+    private function build_result_column($item, $ignore_score_color)
+    {
 		$scoredisplay = ScoreDisplay::instance();
 		$score 	      = $item->calc_score(api_get_user_id());
 
@@ -220,7 +245,8 @@ class GradebookDataGenerator
         return null;
 	}
 
-	private function build_date_column($item) {
+    private function build_date_column($item)
+    {
 		$date = $item->get_date();
 		if (!isset($date) || empty($date)) {
 			return '';

+ 160 - 64
main/gradebook/lib/gradebook_functions.inc.php

@@ -16,6 +16,7 @@ require_once 'gradebook_functions_users.inc.php';
 
 /**
  * Adds a resource to the unique gradebook of a given course
+ * @param   int
  * @param   string  Course code
  * @param   int     Resource type (use constants defined in linkfactory.class.php)
  * @param   int     Resource ID in the corresponding tool
@@ -23,12 +24,24 @@ require_once 'gradebook_functions_users.inc.php';
  * @param   int     Resource weight to set in the gradebook
  * @param   int     Resource max
  * @param   string  Resource description
- * @param   string  Date
  * @param   int     Visibility (0 hidden, 1 shown)
  * @param   int     Session ID (optional or 0 if not defined)
+ * @param   int
  * @return  boolean True on success, false on failure
  */
-function add_resource_to_course_gradebook($category_id, $course_code, $resource_type, $resource_id, $resource_name='', $weight=0, $max=0, $resource_description='',  $visible =  0, $session_id = 0, $link_id = null) {
+function add_resource_to_course_gradebook(
+    $category_id,
+    $course_code,
+    $resource_type,
+    $resource_id,
+    $resource_name = '',
+    $weight = 0,
+    $max = 0,
+    $resource_description = '',
+    $visible = 0,
+    $session_id = 0,
+    $link_id = null
+) {
     $link = LinkFactory :: create($resource_type);
     $link->set_user_id(api_get_user_id());
     $link->set_course_code($course_code);
@@ -63,9 +76,12 @@ function add_resource_to_course_gradebook($category_id, $course_code, $resource_
 /**
  * Update a resource weight
  * @param    int     Link/Resource ID
+ * @param   string
+ * @param float
  * @return   bool    false on error, true on success
  */
-function update_resource_from_course_gradebook($link_id, $course_code, $weight) {
+function update_resource_from_course_gradebook($link_id, $course_code, $weight)
+{
     $course_code = Database::escape_string($course_code);
     if (!empty($link_id)) {
         $link_id = intval($link_id);
@@ -83,18 +99,20 @@ function update_resource_from_course_gradebook($link_id, $course_code, $weight)
  * @param    int     Link/Resource ID
  * @return   bool    false on error, true on success
  */
-function remove_resource_from_course_gradebook($link_id) {
+function remove_resource_from_course_gradebook($link_id)
+{
     if (empty($link_id)) {
         return false;
     }
     // TODO find the corresponding category (the first one for this course, ordered by ID)
     $l = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
     $sql = "DELETE FROM $l WHERE id = ".(int)$link_id;
-    $res = Database::query($sql);
+    Database::query($sql);
     return true;
 }
 
-function block_students() {
+function block_students()
+{
     if (!api_is_allowed_to_edit()) {
 		api_not_allowed();
 	}
@@ -104,7 +122,8 @@ function block_students() {
  * Returns the course name from a given code
  * @param string $code
  */
-function get_course_name_from_code($code) {
+function get_course_name_from_code($code)
+{
 	$tbl_main_categories= Database :: get_main_table(TABLE_MAIN_COURSE);
 	$sql= 'SELECT title, code FROM ' . $tbl_main_categories . 'WHERE code = "' . Database::escape_string($code) . '"';
 	$result= Database::query($sql);
@@ -117,7 +136,8 @@ function get_course_name_from_code($code) {
  * Builds an img tag for a gradebook item
  * @param string $type value returned by a gradebookitem's get_icon_name()
  */
-function build_type_icon_tag($kind, $attributes = array()) {
+function build_type_icon_tag($kind, $attributes = array())
+{
 	return Display::return_icon(get_icon_file_name($kind), ' ', $attributes, ICON_SIZE_SMALL);
 }
 
@@ -125,7 +145,8 @@ function build_type_icon_tag($kind, $attributes = array()) {
  * Returns the icon filename for a gradebook item
  * @param string $type value returned by a gradebookitem's get_icon_name()
  */
-function get_icon_file_name ($type) {
+function get_icon_file_name($type)
+{
 	switch ($type) {
 		case 'cat':
 			$icon = 'gradebook.png';
@@ -179,11 +200,13 @@ function get_icon_file_name ($type) {
  * @param object $cat category object
  * @param int $selectcat id of selected category
  */
-function build_edit_icons_cat($cat, $selectcat) {
+function build_edit_icons_cat($cat, $selectcat)
+{
 	$show_message = $cat->show_message_resource_delete($cat->get_course_code());
     $grade_model_id = $selectcat->get_grade_model_id();
 
     $selectcat = $selectcat->get_id();
+    $modify_icons = null;
 
 	if ($show_message === false) {
 		$visibility_icon= ($cat->is_visible() == 0) ? 'invisible' : 'visible';
@@ -246,7 +269,8 @@ function build_edit_icons_cat($cat, $selectcat) {
  * @param object $eval evaluation object
  * @param int $selectcat id of selected category
  */
-function build_edit_icons_eval($eval, $selectcat) {
+function build_edit_icons_eval($eval, $selectcat)
+{
 	$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
 	$is_locked = $eval->is_locked();
 	$eval->get_course_code();
@@ -290,7 +314,8 @@ function build_edit_icons_eval($eval, $selectcat) {
  * @param object $linkobject
  * @param int $selectcat id of selected category
  */
-function build_edit_icons_link($link, $selectcat) {
+function build_edit_icons_link($link, $selectcat)
+{
 	$cat = new Category();
 	$message_link = $cat->show_message_resource_delete($link->get_course_code());
     $is_locked = $link->is_locked();
@@ -335,13 +360,13 @@ function build_edit_icons_link($link, $selectcat) {
  * @param    int     Session ID (optional -  0 if not defined)
  * @return   int     false on error or link ID
  */
-function is_resource_in_course_gradebook($course_code, $resource_type, $resource_id, $session_id = 0) {
-    // TODO find the corresponding category (the first one for this course, ordered by ID)
-    $t = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
+function is_resource_in_course_gradebook($course_code, $resource_type, $resource_id, $session_id = 0)
+{
     $l = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
 
     $course_code = Database::escape_string($course_code);
-    $sql = "SELECT * FROM $l WHERE course_code = '$course_code' AND type = ".(int) $resource_type." and ref_id = ".(int) $resource_id;
+    $sql = "SELECT * FROM $l l
+            WHERE course_code = '$course_code' AND type = ".(int)$resource_type . " AND ref_id = " . (int)$resource_id;
     $res = Database::query($sql);
     if (Database::num_rows($res)<1) {
     	return false;
@@ -355,7 +380,8 @@ function is_resource_in_course_gradebook($course_code, $resource_type, $resource
  * @param    int     Link/Resource ID
  * @return   bool    false on error, true on success
  */
-function get_resource_from_course_gradebook($link_id) {
+function get_resource_from_course_gradebook($link_id)
+{
     if (empty($link_id)) {
         return false;
     }
@@ -375,11 +401,14 @@ function get_resource_from_course_gradebook($link_id) {
  * @param    int
  * @return   String
  */
-function get_database_name_by_link_id($id_link) {
+function get_database_name_by_link_id($id_link)
+{
 	$course_table 		= Database::get_main_table(TABLE_MAIN_COURSE);
 	$tbl_grade_links 	= Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-	$sql = 'SELECT db_name FROM '.$course_table.' c INNER JOIN '.$tbl_grade_links.' l
-			ON c.code=l.course_code WHERE l.id='.intval($id_link).' OR l.category_id='.intval($id_link);
+    $sql = 'SELECT db_name FROM ' . $course_table . ' c
+            INNER JOIN ' . $tbl_grade_links . ' l
+			ON c.code=l.course_code
+			WHERE l.id=' . intval($id_link) . ' OR l.category_id=' . intval($id_link);
 	$res=Database::query($sql);
 	$my_db_name=Database::fetch_array($res,'ASSOC');
 	return $my_db_name['db_name'];
@@ -390,23 +419,47 @@ function get_database_name_by_link_id($id_link) {
 * @param    int
 * @return   String
 */
-function get_course_id_by_link_id($id_link) {
+function get_course_id_by_link_id($id_link)
+{
 	$course_table 		= Database::get_main_table(TABLE_MAIN_COURSE);
 	$tbl_grade_links 	= Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
-	$sql = 'SELECT c.id FROM '.$course_table.' c INNER JOIN '.$tbl_grade_links.' l
-			ON c.code = l.course_code WHERE l.id='.intval($id_link).' OR l.category_id='.intval($id_link);
+    $sql = 'SELECT c.id FROM ' . $course_table . ' c
+            INNER JOIN ' . $tbl_grade_links . ' l
+			ON c.code = l.course_code
+			WHERE l.id=' . intval($id_link) . ' OR l.category_id=' . intval($id_link);
 	$res = Database::query($sql);
 	$array = Database::fetch_array($res,'ASSOC');
 	return $array['id'];
 }
 
-function get_table_type_course($type) {
+/**
+ * @param $type
+ * @return string
+ */
+function get_table_type_course($type)
+{
 	global $table_evaluated;
 	return Database::get_course_table($table_evaluated[$type][0]);
 }
 
-function get_printable_data($cat, $users, $alleval, $alllinks, $params) {
-	$datagen = new FlatViewDataGenerator ($users, $alleval, $alllinks, $params);
+/**
+ * @param Category $cat
+ * @param $users
+ * @param $alleval
+ * @param $alllinks
+ * @param $params
+ * @param null $mainCourseCategory
+ * @return array
+ */
+function get_printable_data($cat, $users, $alleval, $alllinks, $params, $mainCourseCategory = null)
+{
+    $datagen = new FlatViewDataGenerator(
+        $users,
+        $alleval,
+        $alllinks,
+        $params,
+        $mainCourseCategory
+    );
 
 	$offset = isset($_GET['offset']) ? $_GET['offset'] : '0';
 	$offset = intval($offset);
@@ -416,13 +469,21 @@ function get_printable_data($cat, $users, $alleval, $alllinks, $params) {
 
 	$count = (($offset + 10) > $datagen->get_total_items_count()) ? ($datagen->get_total_items_count() - $offset) : LIMIT;
 	$header_names = $datagen->get_header_names($offset, $count, true);
-	$data_array   = $datagen->get_data(FlatViewDataGenerator :: FVDG_SORT_LASTNAME, 0, null, $offset, $count, true, true);
+    $data_array = $datagen->get_data(
+        FlatViewDataGenerator :: FVDG_SORT_LASTNAME,
+        0,
+        null,
+        $offset,
+        $count,
+        true,
+        true
+    );
 
-	$newarray = array();
+    $result = array();
 	foreach ($data_array as $data) {
-		$newarray[] = array_slice($data, 1);
+        $result[] = array_slice($data, 1);
 	}
-    $return = array($header_names, $newarray);
+    $return = array($header_names, $result);
 	return $return;
 }
 
@@ -431,7 +492,8 @@ function get_printable_data($cat, $users, $alleval, $alllinks, $params) {
  * XML-parser: handle character data
  */
 
-function character_data($parser, $data) {
+function character_data($parser, $data)
+{
 	global $current_value;
 	$current_value= $data;
 }
@@ -440,7 +502,8 @@ function character_data($parser, $data) {
  * XML-parser: handle end of element
  */
 
-function element_end($parser, $data) {
+function element_end($parser, $data)
+{
 	global $user;
 	global $users;
 	global $current_value;
@@ -458,7 +521,8 @@ function element_end($parser, $data) {
  * XML-parser: handle start of element
  */
 
-function element_start($parser, $data) {
+function element_start($parser, $data)
+{
 	global $user;
 	global $current_tag;
 	switch ($data) {
@@ -470,7 +534,8 @@ function element_start($parser, $data) {
 	}
 }
 
-function overwritescore($resid, $importscore, $eval_max) {
+function overwritescore($resid, $importscore, $eval_max)
+{
 	$result= Result :: load($resid);
 	if ($importscore > $eval_max) {
 		header('Location: gradebook_view_result.php?selecteval=' .Security::remove_XSS($_GET['selecteval']) . '&overwritemax=');
@@ -487,7 +552,8 @@ function overwritescore($resid, $importscore, $eval_max) {
  * @return array All userinformation read from the file
  */
 
-function parse_xml_data($file) {
+function parse_xml_data($file)
+{
 	global $current_tag;
 	global $current_value;
 	global $user;
@@ -512,16 +578,17 @@ function parse_xml_data($file) {
 * @param Datetime The date when you obtained the certificate
 * @return void()
 */
-function register_user_info_about_certificate ($cat_id, $user_id, $score_certificate, $date_certificate) {
+function register_user_info_about_certificate($cat_id, $user_id, $score_certificate, $date_certificate)
+{
     $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
-    $sql_exist='SELECT COUNT(*) as count FROM '.$table_certificate.' gc
+    $sql = 'SELECT COUNT(*) as count FROM ' . $table_certificate . ' gc
     			WHERE gc.cat_id="'.intval($cat_id).'" AND user_id="'.intval($user_id).'" ';
-    $rs_exist=Database::query($sql_exist);
+    $rs_exist = Database::query($sql);
     $row=Database::fetch_array($rs_exist);
     if ($row['count']==0) {
     	$sql='INSERT INTO '.$table_certificate.' (cat_id,user_id,score_certificate,created_at)
     		  VALUES("'.intval($cat_id).'","'.intval($user_id).'","'.Database::escape_string($score_certificate).'","'.Database::escape_string($date_certificate).'")';
-    	$rs = Database::query($sql);
+        Database::query($sql);
     }
 }
 
@@ -531,11 +598,13 @@ function register_user_info_about_certificate ($cat_id, $user_id, $score_certifi
 * @param int The user id
 * @return Datetime The date when you obtained the certificate
 */
-function get_certificate_by_user_id ($cat_id,$user_id) {
+function get_certificate_by_user_id($cat_id, $user_id)
+{
 	$table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
-    $sql_get_date = 'SELECT * FROM ' . $table_certificate . ' WHERE cat_id="' . intval($cat_id) . '" AND user_id="' . intval($user_id) . '"';
-	$rs_get_date=Database::query($sql_get_date);
-	$row =Database::fetch_array($rs_get_date,'ASSOC');
+    $sql = 'SELECT * FROM ' . $table_certificate . '
+            WHERE cat_id="' . intval($cat_id) . '" AND user_id="' . intval($user_id) . '"';
+    $result = Database::query($sql);
+    $row = Database::fetch_array($result, 'ASSOC');
 	return $row;
 }
 
@@ -544,11 +613,13 @@ function get_certificate_by_user_id ($cat_id,$user_id) {
 * @param int The category id
 * @return array
 */
-function get_list_users_certificates ($cat_id=null) {
+function get_list_users_certificates($cat_id = null)
+{
     $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
     $table_user = Database::get_main_table(TABLE_MAIN_USER);
     $sql = 'SELECT DISTINCT u.user_id, u.lastname, u.firstname, u.username
-    		FROM '.$table_user.' u INNER JOIN '.$table_certificate.' gc ON u.user_id=gc.user_id ';
+    		FROM ' . $table_user . ' u
+    		INNER JOIN ' . $table_certificate . ' gc ON u.user_id=gc.user_id ';
     if (!is_null($cat_id) && $cat_id>0) {
     	$sql.=' WHERE cat_id='.Database::escape_string($cat_id);
     }
@@ -567,9 +638,11 @@ function get_list_users_certificates ($cat_id=null) {
 *@param int The category id
 *@return array
 */
-function get_list_gradebook_certificates_by_user_id ($user_id,$cat_id=null) {
+function get_list_gradebook_certificates_by_user_id($user_id, $cat_id = null)
+{
     $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
-    $sql='SELECT gc.score_certificate, gc.created_at, gc.path_certificate, gc.cat_id, gc.user_id, gc.id FROM  '.$table_certificate.' gc
+    $sql = 'SELECT gc.score_certificate, gc.created_at, gc.path_certificate, gc.cat_id, gc.user_id, gc.id
+            FROM  ' . $table_certificate . ' gc
     	  WHERE gc.user_id="'.Database::escape_string($user_id).'" ';
     if (!is_null($cat_id) && $cat_id>0) {
     	$sql.=' AND cat_id='.Database::escape_string($cat_id);
@@ -583,16 +656,27 @@ function get_list_gradebook_certificates_by_user_id ($user_id,$cat_id=null) {
     return $list_certificate;
 }
 
-function get_user_certificate_content($user_id, $course_code, $is_preview = false, $hide_print_button = false) {
+function get_user_certificate_content($user_id, $course_code, $is_preview = false, $hide_print_button = false)
+{
     //generate document HTML
     $content_html       = DocumentManager::replace_user_info_into_html($user_id, $course_code, $is_preview);
+    $new_content_html = null;
+    $variables = null;
+    $contentHead = null;
 
+    if (isset($content_html['content'])) {
     $new_content        = explode('</head>', $content_html['content']);
     $new_content_html   = $new_content[1];
+        $contentHead = $new_content[0];
+    }
+
+    if (isset($content_html['variables'])) {
+        $variables = $content_html['variables'];
+    }
     $path_image         = api_get_path(WEB_COURSE_PATH).api_get_course_path($course_code).'/document/images/gallery';
     $new_content_html   = str_replace('../images/gallery',$path_image,$new_content_html);
 
-    $path_image_in_default_course = api_get_path(WEB_DEFAULT_COURSE_DOCUMENT_PATH);
+    $path_image_in_default_course = api_get_path(WEB_CODE_PATH) . 'default_course_document';
     $new_content_html   = str_replace('/main/default_course_document',$path_image_in_default_course,$new_content_html);
     $new_content_html   = str_replace('/main/img/', api_get_path(WEB_IMG_PATH), $new_content_html);
 
@@ -604,12 +688,17 @@ function get_user_certificate_content($user_id, $course_code, $is_preview = fals
     }
 
     //add header
-    $new_content_html = $new_content[0].$print.'</head>'.$new_content_html;
-    return array('content' => $new_content_html, 'variables'=>$content_html['variables']);
+    $new_content_html =  $contentHead. $print . '</head>' . $new_content_html;
+
+    return array(
+        'content' => $new_content_html,
+        'variables' => $variables
+    );
 }
 
-function create_default_course_gradebook($course_code = null, $gradebook_model_id = 0, $session_id = null) {
-    $category_id = null;
+function create_default_course_gradebook($course_code = null, $gradebook_model_id = 0)
+{
+    if (api_is_allowed_to_edit(true, true)) {
     //if (api_is_allowed_to_edit(true, true)) {
         if (!isset($course_code) || empty($course_code)) {
             $course_code = api_get_course_id();
@@ -617,7 +706,6 @@ function create_default_course_gradebook($course_code = null, $gradebook_model_i
 
         if (empty($session_id)) {
             $session_id = api_get_session_id();
-        }
 
         $t = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
         $sql = "SELECT * FROM $t WHERE course_code = '".Database::escape_string($course_code)."' ";
@@ -632,7 +720,8 @@ function create_default_course_gradebook($course_code = null, $gradebook_model_i
             //there is no unique category for this course+session combination,
             $cat = new Category();
             if (!empty($session_id)) {
-                $s_name = api_get_session_name($session_id);
+                $my_session_id = api_get_session_id();
+                $s_name = api_get_session_name($my_session_id);
                 $cat->set_name($course_code.' - '.get_lang('Session').' '.$s_name);
                 $cat->set_session_id($session_id);
             } else {
@@ -656,16 +745,16 @@ function create_default_course_gradebook($course_code = null, $gradebook_model_i
             $category_id = $row['id'];
         }
     //}
+    }
     return $category_id;
 }
-function load_gradebook_select_in_tool($form) {
 
+function load_gradebook_select_in_tool($form)
+{
     $course_code = api_get_course_id();
     $session_id = api_get_session_id();
 
-    if (api_is_allowed_to_edit(true, true)) {
-        create_default_course_gradebook();
-    }
+    create_default_course_gradebook();
 
     //Cat list
     $all_categories = Category :: load(null, null, $course_code, null, null, $session_id, false);
@@ -696,12 +785,18 @@ function load_gradebook_select_in_tool($form) {
 }
 
 /**
- * PDF report creation
+ * @param FlatViewTable $flatviewtable
+ * @param Category $cat
+ * @param $users
+ * @param $alleval
+ * @param $alllinks
+ * @param array $params
+ * @param null $mainCourseCategory
  */
-function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array()) {
-    global $flatviewtable;
+function export_pdf_flatview($flatviewtable, $cat, $users, $alleval, $alllinks, $params = array(), $mainCourseCategory = null)
+{
     //Getting data
-    $printable_data = get_printable_data($cat[0], $users, $alleval, $alllinks, $params);
+    $printable_data = get_printable_data($cat[0], $users, $alleval, $alllinks, $params, $mainCourseCategory);
 
     // HTML report creation first
     $course_code = trim($cat[0]->get_course_code());
@@ -811,7 +906,8 @@ function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array(
     exit;
 }
 
-function score_badges($list_values) {
+function score_badges($list_values)
+{
     $counter = 1;
     $badges = array();
     foreach ($list_values as $value) {

+ 27 - 15
main/gradebook/lib/results_data_generator.class.php

@@ -1,15 +1,12 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
+ * ResultsDataGenerator Class
  * Class to select, sort and transform object data into array data,
  * used for the teacher's evaluation results view
  * @author Bert Steppé
  * @package chamilo.gradebook
  */
-/**
- * Class
- * @package chamilo.gradebook
- */
 class ResultsDataGenerator
 {
 
@@ -32,9 +29,11 @@ class ResultsDataGenerator
 	/**
 	 * Constructor
 	 */
-    function ResultsDataGenerator ( $evaluation,
-    								$results = array(),
-    								$include_edit = false) {
+    public function ResultsDataGenerator(
+        $evaluation,
+		$results = array(),
+        $include_edit = false
+    ) {
     	$this->evaluation = $evaluation;
 		$this->results = (isset($results) ? $results : array());
     }
@@ -43,7 +42,8 @@ class ResultsDataGenerator
 	/**
 	 * Get total number of results (rows)
 	 */
-	public function get_total_results_count () {
+    public function get_total_results_count ()
+    {
 		return count($this->results);
 	}
 
@@ -58,7 +58,8 @@ class ResultsDataGenerator
 	 * 4 ['score']     : student's score
 	 * 5 ['display']   : custom score display (only if custom scoring enabled)
 	 */
-	public function get_data ($sorting = 0, $start = 0, $count = null, $ignore_score_color = false, $pdf=false) {
+    public function get_data ($sorting = 0, $start = 0, $count = null, $ignore_score_color = false, $pdf=false)
+    {
 
 		// do some checks on count, redefine if invalid value
 		$number_decimals = api_get_setting('gradebook_number_decimals');
@@ -86,7 +87,13 @@ class ResultsDataGenerator
 			} else {
 				$user['score'] = $this->get_score_display($result->get_score(),true, $ignore_score_color);
 			}
-            $user['percentage_score'] = intval($scoredisplay->display_score(array($result->get_score(), $this->evaluation->get_max()), SCORE_PERCENT, SCORE_BOTH, true));
+            $user['percentage_score'] = intval($scoredisplay->display_score(
+                    array($result->get_score(), $this->evaluation->get_max()),
+                    SCORE_PERCENT,
+                    SCORE_BOTH,
+                    true
+                )
+            );
 			if ($pdf && $number_decimals == null){
 				$user['scoreletter'] = $result->get_score();
 			}
@@ -122,7 +129,8 @@ class ResultsDataGenerator
      * @param bool  Whether we want to ignore the score color
      * @result string The score as we want to show it
      */
-    private function get_score_display ($score, $realscore, $ignore_score_color = false) {
+    private function get_score_display ($score, $realscore, $ignore_score_color = false)
+    {
 		if ($score != null) {
 			$scoredisplay = ScoreDisplay :: instance();
 			$type = SCORE_CUSTOM;
@@ -135,15 +143,18 @@ class ResultsDataGenerator
 	}
 
 	// Sort functions - used internally
-	function sort_by_last_name($item1, $item2) {
+    function sort_by_last_name($item1, $item2)
+    {
 		return api_strcmp($item1['lastname'], $item2['lastname']);
 	}
 
-	function sort_by_first_name($item1, $item2) {
+    function sort_by_first_name($item1, $item2)
+    {
 		return api_strcmp($item1['firstname'], $item2['firstname']);
 	}
 
-	function sort_by_score($item1, $item2) {
+    function sort_by_score($item1, $item2)
+    {
 		if ($item1['percentage_score'] == $item2['percentage_score']) {
 			return 0;
 		} else {
@@ -151,7 +162,8 @@ class ResultsDataGenerator
 		}
 	}
 
-	function sort_by_mask ($item1, $item2) {
+    function sort_by_mask ($item1, $item2)
+    {
 		$score1 = (isset($item1['score']) ? array($item1['score'],$this->evaluation->get_max()) : null);
 		$score2 = (isset($item2['score']) ? array($item2['score'],$this->evaluation->get_max()) : null);
 		return ScoreDisplay :: compare_scores_by_custom_display($score1, $score2);

+ 67 - 29
main/gradebook/lib/scoredisplay.class.php

@@ -44,7 +44,8 @@ class ScoreDisplay
     /**
      * Get the instance of this class
      */
-    public static function instance($category_id = 0) {
+    public static function instance($category_id = 0)
+    {
         static $instance;
         if (!isset ($instance)) {
             $instance = new ScoreDisplay($category_id);
@@ -58,7 +59,8 @@ class ScoreDisplay
     /**
      * Compare the custom display of 2 scores, can be useful in sorting
      */
-    public static function compare_scores_by_custom_display ($score1, $score2) {
+    public static function compare_scores_by_custom_display ($score1, $score2)
+    {
         if (!isset($score1)) {
             return (isset($score2) ? 1 : 0);
         } elseif (!isset($score2)) {
@@ -86,7 +88,8 @@ class ScoreDisplay
     /**
      * Protected constructor - call instance() to instantiate
      */
-    protected function ScoreDisplay($category_id = 0) {
+    protected function ScoreDisplay($category_id = 0)
+    {
         if (!empty($category_id)) {
             $this->category_id = $category_id;
         }
@@ -112,12 +115,15 @@ class ScoreDisplay
         $this->custom_enabled  = $value == 'true' ? true : false;
         
         if ($this->custom_enabled) {
-            $params = array('category = ? AND subkey = ?' =>  array('Gradebook', 'ranking'));
+            $params = array('category = ?' =>  array('Gradebook'));
             $displays = api_get_settings_params($params);
             $portal_displays = array();
             if (!empty($displays)) {
                 foreach ($displays as $display) {
                     $data = explode('::', $display['selected_value']);
+                    if (empty($data[1])) {
+                        $data[1] = "";
+                    }
                     $portal_displays[$data[0]] = array('score' => $data[0], 'display' =>$data[1]);
                 }
                 sort($portal_displays);
@@ -151,7 +157,8 @@ class ScoreDisplay
     /**
      * Is coloring enabled ?
      */
-    public function is_coloring_enabled () {
+    public function is_coloring_enabled ()
+    {
         return $this->coloring_enabled;
     }
     
@@ -165,7 +172,8 @@ class ScoreDisplay
     /**
      * Is upperlimit included ?
      */
-    public function is_upperlimit_included () {
+    public function is_upperlimit_included ()
+    {
         return $this->upperlimit_included;
     }
 
@@ -174,7 +182,8 @@ class ScoreDisplay
      * See also update_custom_score_display_settings
      * @return array current settings (or null if feature not enabled)
      */
-    public function get_custom_score_display_settings() {
+    public function get_custom_score_display_settings()
+    {
         return $this->custom_display;
     }
 
@@ -182,7 +191,8 @@ class ScoreDisplay
      * If coloring is enabled, scores below this value will be displayed in red.
      * @return int color split value, in percent (or null if feature not enabled)
      */
-    public function get_color_split_value() {
+    public function get_color_split_value()
+    {
         return $this->color_split_value;
     }
 
@@ -190,13 +200,13 @@ class ScoreDisplay
      * Get current gradebook category id
      * @return int  Category id
      */
-    private function get_current_gradebook_category_id() {
+    private function get_current_gradebook_category_id()
+    {
 
         $tbl_gradebook_category = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
         $curr_course_code       = api_get_course_id();
         $curr_session_id        = api_get_session_id();
 
-        $session_condition = '';
         if (empty($curr_session_id)) {
             $session_condition = ' AND session_id is null ';
         } else {
@@ -219,7 +229,8 @@ class ScoreDisplay
          * @param int   score color percent (optional)
          * @param int   gradebook category id (optional)
      */
-    public function update_custom_score_display_settings ($displays, $scorecolpercent = 0, $category_id = null) {
+    public function update_custom_score_display_settings ($displays, $scorecolpercent = 0, $category_id = null)
+    {
         $this->custom_display = $displays;
            $this->custom_display_conv = $this->convert_displays($this->custom_display);
 
@@ -247,7 +258,8 @@ class ScoreDisplay
         Database::query($sql);
     }
     
-    public function insert_defaults($category_id) {
+    public function insert_defaults($category_id)
+    {
         if (empty($category_id)) {
             return false;
         }
@@ -272,10 +284,10 @@ class ScoreDisplay
             );
             Database::insert($tbl_display, $params);            
         }
-        Database::query($sql);        
     }
     
-    public function get_number_decimals() {
+    public function get_number_decimals()
+    {
         $number_decimals = api_get_setting('gradebook_number_decimals');        
         if (!isset($number_decimals)) {
             $number_decimals = 0;
@@ -286,22 +298,28 @@ class ScoreDisplay
     /**
      * Formats a number depending of the number of decimals
      * 
-     * @param float a score
+     * @param float $score
      * @return float the score formatted
      */
-    public function format_score($score) {        
+    public function format_score($score)
+    {
         return floatval(number_format($score, $this->get_number_decimals()));
     }
 
     /**
      * Display a score according to the current settings
-     * @param array $score score data structure, as returned by the calc_score functions
-	 * @param int 	$type one of the following constants: SCORE_DIV, SCORE_PERCENT, SCORE_DIV_PERCENT, SCORE_AVERAGE
+     * @param array $score data structure, as returned by the calc_score functions
+     * @param int $type one of the following constants:
+     * SCORE_DIV, SCORE_PERCENT, SCORE_DIV_PERCENT, SCORE_AVERAGE
 	 * 				(ignored for student's view if custom score display is enabled)
-	 * @param int 	$what one of the following constants: SCORE_BOTH, SCORE_ONLY_DEFAULT, SCORE_ONLY_CUSTOM (default: SCORE_BOTH)
+     * @param int $what one of the following constants:
+     * SCORE_BOTH, SCORE_ONLY_DEFAULT, SCORE_ONLY_CUSTOM (default: SCORE_BOTH)
 	 * 				(only taken into account if custom score display is enabled and for course/platform admin)
+     *
+     * @return string
      */
-    public function display_score($score, $type = SCORE_DIV_PERCENT, $what = SCORE_BOTH, $no_color = false) {      
+    public function display_score($score, $type = SCORE_DIV_PERCENT, $what = SCORE_BOTH, $no_color = false)
+    {
         $my_score = $score == 0 ? 1 : $score;    
         
         if ($type == SCORE_BAR) {
@@ -380,7 +398,12 @@ class ScoreDisplay
         }
     }
     
-    private function display_simple_score($score) {
+    /**
+     * @param array $score
+     * @return float|string
+     */
+    private function display_simple_score($score)
+    {
         if (isset($score[0])) {
             return $this->format_score($score[0]);
         }
@@ -389,8 +412,11 @@ class ScoreDisplay
     
     /**
      * Returns "1" for array("100", "100");
+     * @param array $score
+     * @return float
      */
-    private function display_as_decimal($score) {
+    private function display_as_decimal($score)
+    {
         $score_denom = ($score[1]==0) ? 1 : $score[1];
         return $this->format_score($score[0]/$score_denom);
     }
@@ -398,7 +424,8 @@ class ScoreDisplay
     /**
      * Returns "100 %" for array("100", "100");
      */
-    private function display_as_percent($score) {        
+    private function display_as_percent($score)
+    {
         $score_denom = ($score[1]==0) ? 1 : $score[1];        
         return $this->format_score($score[0]/$score_denom*100) . ' %';
     }
@@ -408,7 +435,8 @@ class ScoreDisplay
      * Returns 10.00 / 10.00 for array("100", "100");
      * @param array $score
      */    
-    private function display_as_div($score) {
+    private function display_as_div($score)
+    {
         if ($score == 1) {
             return '0/0';
         } else {
@@ -422,7 +450,8 @@ class ScoreDisplay
      * Depends on the teacher's configuration of thresholds. i.e. [0 50] "Bad", [50:100] "Good"
      * @param array $score
      */    
-    private function display_custom ($score) {
+    private function display_custom ($score)
+    {
         $my_score_denom= ($score[1]==0) ? 1 : $score[1];
         $scaledscore = $score[0] / $my_score_denom;
         if ($this->upperlimit_included) {
@@ -448,7 +477,8 @@ class ScoreDisplay
      * @param   int Gradebook category id
      * @return  int Score
      */
-    private function get_score_color_percent($category_id = null) {
+    private function get_score_color_percent($category_id = null)
+    {
         $tbl_display = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY);
         if (isset($category_id)) {
             $category_id = intval($category_id);
@@ -471,7 +501,8 @@ class ScoreDisplay
          * @param   int     Gradebook category id
      * @return  array   2-dimensional array - every element contains 3 subelements (id, score, display)
      */
-    private function get_custom_displays($category_id = null) {
+    private function get_custom_displays($category_id = null)
+    {
         $tbl_display = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_SCORE_DISPLAY);
         if (isset($category_id)) {
             $category_id = intval($category_id);
@@ -487,7 +518,8 @@ class ScoreDisplay
     /**
      * Convert display settings to internally used values
      */
-    private function convert_displays($custom_display) {
+    private function convert_displays($custom_display)
+    {
         if (isset($custom_display)) {
             // get highest score entry, and copy each element to a new array
             $converted = array();
@@ -521,7 +553,13 @@ class ScoreDisplay
         }
     }
 
-    private function sort_display($item1, $item2) {
+    /**
+     * @param array $item1
+     * @param array $item2
+     * @return int
+     */
+    private function sort_display($item1, $item2)
+    {
         if ($item1['score'] == $item2['score']) {
             return 0;
         } else {

+ 18 - 4
main/group/group.php

@@ -170,6 +170,8 @@ if (api_is_allowed_to_edit(false, true)) {
     echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_pdf">'.
         Display::return_icon('pdf.png', get_lang('ExportToPDF'), '', ICON_SIZE_MEDIUM).'</a>';
 
+    echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_all&type=xls">'.
+        Display::return_icon('export_excel.png', get_lang('ExportSettingsAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
     echo '<a href="group_overview.php?'.api_get_cidreq().'">'.
         Display::return_icon('group_summary.png', get_lang('GroupOverview'), '', ICON_SIZE_MEDIUM).'</a>';
 
@@ -193,8 +195,14 @@ if (api_get_setting('allow_group_categories') == 'true') {
         if (api_is_allowed_to_edit(false, true)) {
             $actions .= '<a href="group_category.php?'.api_get_cidreq().'&id='.$category['id'].'" title="'.get_lang('Edit').'">'.
                 Display::return_icon('edit.png', get_lang('EditGroup'),'',ICON_SIZE_SMALL).'</a>';
-            $actions .= '<a href="group.php?'.api_get_cidreq().'&action=delete_category&amp;id='.$category['id'].'" onclick="javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('Delete').'">'.
-                Display::return_icon('delete.png', get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>';
+            $actions .=
+                Display::url(
+                    Display::return_icon('delete.png', get_lang('Delete'), '', ICON_SIZE_SMALL),
+                    'group.php?'.api_get_cidreq().'&action=delete_category&amp;id='.$category['id'],
+                    array(
+                        'onclick' => 'javascript:if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;'
+                    )
+                );
             if ($index != 0) {
                 $actions .=  ' <a href="group.php?'.api_get_cidreq().'&action=swap_cat_order&amp;id1='.$category['id'].'&amp;id2='.$group_cats[$index -1]['id'].'">'.
                     Display::return_icon('up.png','&nbsp;','',ICON_SIZE_SMALL).'</a>';
@@ -205,8 +213,14 @@ if (api_get_setting('allow_group_categories') == 'true') {
             }
         }
 
-        echo Display::page_header($category['title'].' '. $label.' '.$actions);
-        echo '<p style="margin: 0px;margin-left: 50px;">'.$category['description'].'</p><p/>';
+        echo Display::page_header(
+            Security::remove_XSS($category['title'].' '. $label.' ').$actions,
+            null,
+            'h2',
+            false
+        );
+
+        echo $category['description'];
         GroupManager ::process_groups($group_list, $category['id']);
     }
 } else {

+ 0 - 1
main/group/import.php

@@ -2,7 +2,6 @@
 /* For licensing terms, see /license.txt */
 
 // Name of the language file that needs to be included
-
 $this_section = SECTION_COURSES;
 $current_course_tool  = TOOL_GROUP;
 

+ 6 - 2
main/inc/lib/api.lib.php

@@ -617,7 +617,7 @@ function api_get_path($path_type, $path = null) {
     // Default $_configuration['root_web'] configuration
     //$root_web = isset($_configuration['root_web']) ? $_configuration['root_web'] : $app['url_generator'];
 
-    $root_web = Session::getUrlGenerator()->generate('root'); //$_configuration['root_web'];
+    $root_web = Session::getUrlGenerator()->generate('home'); //$_configuration['root_web'];
     $rootDir = Session::getRootDir();
 
     // Configuration data for already installed system.
@@ -2991,6 +2991,9 @@ function api_not_allowed($printHeaders = false, $message = null)
  * @desc convert sql date to unix timestamp
  */
 function api_convert_sql_date($last_post_datetime) {
+    if (empty($last_post_datetime)) {
+        return null;
+    }
     list ($last_post_date, $last_post_time) = explode(' ', $last_post_datetime);
     list ($year, $month, $day) = explode('-', $last_post_date);
     list ($hour, $min, $sec) = explode(':', $last_post_time);
@@ -3477,7 +3480,8 @@ function api_get_languages() {
     $language_list = array();
     while ($row = Database::fetch_array($result)) {
         $language_list['name'][] = $row['original_name'];
-        $language_list['folder'][] = $row['dokeos_folder'];
+        //$language_list['folder'][] = $row['dokeos_folder'];
+        $language_list['folder'][] = $row['original_name'];
     }
     Session::write('_setting.api_get_languages', $language_list);
     return $language_list;

+ 27 - 14
main/inc/lib/certificate.lib.php

@@ -1,6 +1,7 @@
 <?php
 /* For licensing terms, see /license.txt */
 /**
+ * Certificate Class
  * The certificates class is used to generate certificates from inside the
  * gradebook tool.
  * @package chamilo.library.certificates
@@ -24,8 +25,11 @@ class Certificate extends Model
     public $qr_file     = null;
     public $sys_qr_file     = null;
     public $user_id;
-
-    //If true every time we enter to the certificate URL we would generate a new certificate
+   
+    /* If true every time we enter to the certificate URL
+    we would generate a new certificate (good thing because we can edit the
+    certificate and all users will have the latest certificate bad because we
+    load the certificate everytime*/
     // (good thing because we can edit the certificate and all users will have the latest certificate bad because we load the certificate everytime)
     public $force_certificate_generation = true;  //default true
 
@@ -33,7 +37,8 @@ class Certificate extends Model
      * Constructor
      * @param	int	ID of the certificate. If no ID given, take user_id and try to generate one
      */
-    public function __construct($certificate_id = null) {
+    public function __construct($certificate_id = null)
+    {
         $this->table             =  Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
         $this->certificate_data = null;
 
@@ -75,13 +80,13 @@ class Certificate extends Model
     /**
      * Checks if the certificate user path directory is created
      */
-    public function check_certificate_path() {
+    public function check_certificate_path()
+    {
         $this->certification_user_path = null;
 
         //Setting certification path
-        $path_info = UserManager::get_user_picture_path_by_id($this->user_id, 'system', true);
-
-        $web_path_info = UserManager::get_user_picture_path_by_id($this->user_id, 'web', true);
+        $path_info = UserManager::get_user_picture_path_by_id($this->user_id, 'system');
+        $web_path_info = UserManager::get_user_picture_path_by_id($this->user_id, 'web');
 
         if (!empty($path_info) && isset($path_info['dir'])) {
 
@@ -135,7 +140,8 @@ class Certificate extends Model
      * Generates an HTML Certificate and fills the path_certificate field in the DB
      * */
 
-    public function generate($params = array()) {
+    public function generate($params = array())
+    {
         //The user directory should be set
         if (empty($this->certification_user_path) && $this->force_certificate_generation == false) {
             return false;
@@ -191,7 +197,7 @@ class Certificate extends Model
                             $file_info = pathinfo($path_certificate);
                             $qr_code_filename = $this->certification_user_path.$file_info['filename'].'_qr.png';
 
-                            $my_new_content_html = str_replace('((certificate_barcode))', Display::img($this->certification_web_user_path.$file_info['filename'].'_qr.png', 'QR', null, false), $new_content_html['content']);
+                            $my_new_content_html = str_replace('((certificate_barcode))', Display::img($this->certification_web_user_path.$file_info['filename'].'_qr.png', 'QR'), $new_content_html['content']);
                             $my_new_content_html = mb_convert_encoding($my_new_content_html,'UTF-8', api_get_system_encoding());
 
                             $result = @file_put_contents($my_path_certificate, $my_new_content_html);
@@ -223,7 +229,8 @@ class Certificate extends Model
     * @param string the path name of the certificate
     * @return void()
     */
-    function update_user_info_about_certificate ($cat_id,$user_id,$path_certificate) {
+    public function update_user_info_about_certificate ($cat_id,$user_id,$path_certificate)
+    {
         $table_certificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
         if (!UserManager::is_user_certified($cat_id,$user_id)) {
             $sql='UPDATE '.$table_certificate.' SET path_certificate="'.Database::escape_string($path_certificate).'"
@@ -238,11 +245,15 @@ class Certificate extends Model
      *
      * @return boolean
      */
-    function html_file_is_generated() {
+    public function html_file_is_generated()
+    {
         if (empty($this->certification_user_path)) {
             return false;
         }
-        if (!empty($this->certificate_data) && isset($this->certificate_data['path_certificate']) && !empty($this->certificate_data['path_certificate'])) {
+        if (!empty($this->certificate_data) &&
+            isset($this->certificate_data['path_certificate']) &&
+            !empty($this->certificate_data['path_certificate'])
+        ) {
             return true;
         }
         return false;
@@ -269,7 +280,8 @@ class Certificate extends Model
      * @param array Contains two array entris: first are the headers, second is an array of contents
      * @return string The translated string
      */
-    public function parse_certificate_variables($array) {
+    public function parse_certificate_variables($array)
+    {
         $text = '';
         $headers = $array[0];
         $content = $array[1];
@@ -319,7 +331,8 @@ class Certificate extends Model
     * course* can be printed (for anonymous users). Connected users can always
     * print them.
     */
-    public function show($returnContent = false) {
+    public function show()
+    {
         // Special rules for anonymous users
         $failed = false;
         if (api_is_anonymous()) {

+ 2 - 2
main/newscorm/lp_list.php

@@ -266,9 +266,9 @@ foreach ($categories as $item) {
 
             $dsp_desc = '';
             $dsp_export = '';
-        $dsp_edit = '';
+            $dsp_edit = '';
             $dsp_build = '';
-        $dsp_edit_close = '';
+            $dsp_edit_close = '';
             $dsp_delete = '';
             $dsp_visible = '';
             $dsp_default_view = '';

Some files were not shown because too many files changed in this diff