Browse Source

Adding group reporting see BT#5758

Julio Montoya 12 years ago
parent
commit
f5d9d34cb6

BIN
main/img/icons/32/group_na.png


+ 2 - 0
main/inc/Entity/EntityPages.php

@@ -7,6 +7,7 @@ use Doctrine\ORM\Mapping as ORM;
 use Doctrine\ORM\Mapping\Id;
 use Doctrine\ORM\Mapping\Column;
 use Doctrine\ORM\Mapping\GeneratedValue;
+use APY\DataGridBundle\Grid\Mapping as GRID;
 
 /**
  * EntityPages
@@ -14,6 +15,7 @@ use Doctrine\ORM\Mapping\GeneratedValue;
  * @Table(name="pages")
  * @Entity(repositoryClass="Entity\Repository\PagesRepository")
  * @HasLifecycleCallbacks()
+ * @GRID\Source(columns="id, title")
  */
 class EntityPages
 {

+ 29 - 18
main/inc/ajax/model.ajax.php

@@ -175,6 +175,11 @@ if (!$sidx) $sidx = 1;
 //@todo rework this
 
 switch ($action) {
+    case 'get_group_reporting':
+        $course_id = isset($_REQUEST['course_id']) ? $_REQUEST['course_id'] : null;
+        $group_id = isset($_REQUEST['gidReq']) ? $_REQUEST['gidReq'] : null;
+        $count = Tracking::get_group_reporting($course_id, $group_id, 'count');
+        break;
     case 'get_user_course_report_resumed':
         $count = CourseManager::get_count_user_list_from_course_code(true, 'ruc');
         break;
@@ -302,6 +307,10 @@ $is_allowedToEdit = api_is_allowed_to_edit(null,true) || api_is_allowed_to_edit(
 $columns = array();
 
 switch ($action) {
+    case 'get_group_reporting':
+        $columns = array('name', 'time', 'progress', 'score', 'works', 'messages', 'actions');
+        $result = Tracking::get_group_reporting($course_id, $group_id, 'all', $start, $limit, $sidx, $sord, $where_condition);
+        break;
     case 'get_course_exercise_medias':
         $columns = array('question');
         $result = Question::get_course_medias($course_id, $start, $limit, $sidx, $sord, $where_condition);
@@ -612,24 +621,26 @@ switch ($action) {
         exit;
 }
 
-$allowed_actions = array('get_careers',
-                         'get_promotions',
-                         'get_usergroups',
-                         'get_usergroups_teacher',
-                         'get_gradebooks',
-                         'get_sessions',
-                         'get_exercise_results',
-                         'get_hotpotatoes_exercise_results',
-                         'get_work_user_list',
-                         'get_timelines',
-                         'get_grade_models',
-                         'get_event_email_template',
-                         'get_user_skill_ranking',
-                         'get_extra_fields',
-                         'get_extra_field_options',
-                         'get_course_exercise_medias',
-                         'get_user_course_report',
-                         'get_user_course_report_resumed'
+$allowed_actions = array(
+    'get_careers',
+    'get_promotions',
+    'get_usergroups',
+    'get_usergroups_teacher',
+    'get_gradebooks',
+    'get_sessions',
+    'get_exercise_results',
+    'get_hotpotatoes_exercise_results',
+    'get_work_user_list',
+    'get_timelines',
+    'get_grade_models',
+    'get_event_email_template',
+    'get_user_skill_ranking',
+    'get_extra_fields',
+    'get_extra_field_options',
+    'get_course_exercise_medias',
+    'get_user_course_report',
+    'get_user_course_report_resumed',
+    'get_group_reporting'
 );
 
 //5. Creating an obj to return a json

+ 13 - 7
main/inc/lib/course.lib.php

@@ -1504,19 +1504,25 @@ class CourseManager {
      *    @param boolean $full list to true if we want sessions students too
      *    @return array with user id
      */
-    public static function get_student_list_from_course_code($course_code, $with_session = false, $session_id = 0) {
+    public static function get_student_list_from_course_code($course_code, $with_session = false, $session_id = 0, $group_id = 0) {
         $session_id = intval($session_id);
         $course_code = Database::escape_string($course_code);
 
         $students = array();
 
         if ($session_id == 0) {
-            // students directly subscribed to the course
-            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
-                   WHERE course_code = '$course_code' AND status = ".STUDENT;
-            $rs = Database::query($sql);
-            while ($student = Database::fetch_array($rs)) {
-                $students[$student['user_id']] = $student;
+            if (empty($group_id)) {
+                // students directly subscribed to the course
+                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
+                       WHERE course_code = '$course_code' AND status = ".STUDENT;
+                $rs = Database::query($sql);
+                while ($student = Database::fetch_array($rs)) {
+                    $students[$student['user_id']] = $student;
+                }
+            } else {
+                $course_info = api_get_course_info($course_code);
+                $students = GroupManager::get_users($group_id, false, $course_info['real_id']);
+                $students = array_flip($students);
             }
         }
 

+ 73 - 73
main/inc/lib/database.lib.php

@@ -19,7 +19,7 @@
  * @package chamilo.database
  */
 class Database {
-    
+
     /* Variable use only in the installation process to log errors. See the Database::query function */
     static $log_queries = false;
 
@@ -132,7 +132,7 @@ class Database {
 
     /**
      * A more generic method than the other get_main_xxx_table methods,
-     * This one returns the correct complete name of any table of the main 
+     * This one returns the correct complete name of any table of the main
      * database of which you pass the short name as a parameter.
      * Please, define table names as constants in this library and use them
      * instead of directly using magic words in your tool code.
@@ -141,14 +141,14 @@ class Database {
      */
     public static function get_main_table($short_table_name) {
         return self::format_table_name(
-          self::get_main_database(), 
+          self::get_main_database(),
           $short_table_name);
     }
 
     /**
 
      * A more generic method than the older get_course_xxx_table methods,
-     * This one can return the correct complete name of any course table of 
+     * This one can return the correct complete name of any course table of
      * which you pass the short name as a parameter.
      * Please, define table names as constants in this library and use them
      * instead of directly using magic words in your tool code.
@@ -158,7 +158,7 @@ class Database {
      * - if you don't specify this, you work on the current course.
      */
     public static function get_course_table($short_table_name, $extra = null) {
-        //forces fatal errors so we can debug more easily        
+        //forces fatal errors so we can debug more easily
         if (!empty($extra)) {
             var_dump($extra);
             //@todo remove this
@@ -170,7 +170,7 @@ class Database {
     }
 
     /**
-     * This generic method returns the correct and complete name of any 
+     * This generic method returns the correct and complete name of any
      * statistic table of which you pass the short name as a parameter.
      * Please, define table names as constants in this library and use them
      * instead of directly using magic words in your tool code.
@@ -268,9 +268,9 @@ class Database {
      *	@author	Roan Embrechts
      *
      * 	@todo What's the use of this method. I think this is better removed.
-     * 		  There should be consistency in the variable names and the 
+     * 		  There should be consistency in the variable names and the
      *            use throughout the scripts
-     * 		  for the database name we should consistently use or db_name 
+     * 		  for the database name we should consistently use or db_name
      *            or database (db_name probably being the better one)
      */
     public static function generate_abstract_course_field_names($result_array) {
@@ -339,7 +339,7 @@ class Database {
      * @return int The number of rows in the given table.
      */
     public static function count_rows($table) {
-        $obj = self::fetch_object(self::query("SELECT COUNT(*) AS n FROM $table"));   // 
+        $obj = self::fetch_object(self::query("SELECT COUNT(*) AS n FROM $table"));   //
         return $obj->n;
     }
 
@@ -396,7 +396,7 @@ class Database {
         if (!isset($parameters['client_flags'])) {
             $parameters['client_flags'] = 0;
         }
-        
+
         $persistent = isset($parameters['persistent']) ? $parameters['persistent'] : null;
         $server = isset($parameters['server']) ? $parameters['server'] : null;
         $username = isset($parameters['username']) ? $parameters['username'] : null;
@@ -411,7 +411,7 @@ class Database {
 
     /**
      * Returns error number from the last operation done on the database server.
-     * @param resource $connection (optional)	The database server connection, 
+     * @param resource $connection (optional)	The database server connection,
      * for detailed description see the method query().
      * @return int Returns the error number from the last database (operation, or 0 (zero) if no error occurred.
      */
@@ -673,20 +673,20 @@ class Database {
             $line = $file;
             $file = $connection;
             $connection = null;
-        }                
+        }
         //@todo remove this before the stable release
-        
+
         //Check if the table contains a c_ (means a course id)
         if (api_get_setting('server_type')==='test' && strpos($query, 'c_')) {
-        	//Check if the table contains inner joins 
-        	if (     
+        	//Check if the table contains inner joins
+        	if (
                 strpos($query, 'assoc_handle') === false &&
                 strpos($query, 'olpc_peru_filter') === false &&
                 strpos($query, 'allow_public_certificates') === false &&
-                strpos($query, 'DROP TABLE IF EXISTS') === false &&      
-                strpos($query, 'thematic_advance') === false &&  
-                strpos($query, 'thematic_plan') === false &&  
-                strpos($query, 'track_c_countries') === false &&                        
+                strpos($query, 'DROP TABLE IF EXISTS') === false &&
+                strpos($query, 'thematic_advance') === false &&
+                strpos($query, 'thematic_plan') === false &&
+                strpos($query, 'track_c_countries') === false &&
                 strpos($query, 'track_c_os') === false &&
                 strpos($query, 'track_c_providers') === false &&
                 strpos($query, 'track_c_referers') === false &&
@@ -705,7 +705,7 @@ class Database {
                 strpos($query, 'wcag_anysurfer_public_pages') === false &&
                 strpos($query, 'specific_field') === false &&
         	    strpos($query, 'down_doc_path') === false &&
-        		strpos($query, 'INNER JOIN') === false &&  
+        		strpos($query, 'INNER JOIN') === false &&
         		strpos($query, 'inner join') === false &&
         		strpos($query, 'left join') === false &&
         		strpos($query, 'LEFT JOIN') === false &&
@@ -716,18 +716,18 @@ class Database {
         		strpos($query, 'c_id') === false &&
         		strpos($query, 'create table') === false &&
         		strpos($query, 'CREATE TABLE') === false &&
-        		strpos($query, 'AUTO_INCREMENT') === false        	
+        		strpos($query, 'AUTO_INCREMENT') === false
         	) {
                 //@todo remove this
                 echo '<pre>';
                 $message = '<h4>Dev message: please add the c_id field in this query or report this error in support.chamilo.org </h4>';
-                $message .= $query;    
+                $message .= $query;
                 echo $message;
-                echo '</pre>';        	    
+                echo '</pre>';
                 //error_log($message);
-        	}        	
-        }        
-        
+        	}
+        }
+
         if (!($result = $use_default_connection ? @mysql_query($query) : @mysql_query($query, $connection))) {
             $backtrace = debug_backtrace(); // Retrieving information about the caller statement.
             if (isset($backtrace[0])) {
@@ -773,18 +773,18 @@ class Database {
                 $info .= '</pre>';
                 echo $info;
             }
-            
+
             if (isset(self::$log_queries) && self::$log_queries) {
                 error_log("----------------  SQL error ---------------- ");
                 error_log($query);
-                
+
                 error_log('error #'.self::errno($connection));
-                error_log('error: '.self::error($connection)); 
-                
-                $info = 'FILE: ' .(empty($file) ? ' unknown ' : $file);                
+                error_log('error: '.self::error($connection));
+
+                $info = 'FILE: ' .(empty($file) ? ' unknown ' : $file);
                 $info .= ' +'.(empty($line) ? ' unknown ' : $line);
                 error_log($info);
-                
+
                 if (empty($type)) {
                     if (!empty($function)) {
                         $info = 'FUNCTION: ' . $function;
@@ -793,7 +793,7 @@ class Database {
                 } else {
                     if (!empty($class) && !empty($function)) {
                         $info = 'CLASS: ' . $class.' METHOD: '.$function;
-                        error_log($info);                        
+                        error_log($info);
                     }
                 }
                 error_log("---------------- end ----------------");
@@ -1006,7 +1006,7 @@ class Database {
         if ($_configuration['single_database']) {
             $table_name =  '`'.$database.'`.`'.$table.'`';
         } else {
-            $table_name =  '`'.$database.$_configuration['db_glue'].$table.'`'; 
+            $table_name =  '`'.$database.$_configuration['db_glue'].$table.'`';
         }
         return $table_name;
     }
@@ -1129,15 +1129,15 @@ class Database {
         $params = array_keys($filtred_attributes); //@todo check if the field exists in the table we should use a describe of that table
         $values = array_values($filtred_attributes);
         if (!empty($params) && !empty($values)) {
-            $sql    = 'INSERT INTO '.$table_name.' ('.implode(', ',$params).') VALUES ('.implode(', ',$values).')';            
-            $result = self::query($sql);            
+            $sql    = 'INSERT INTO '.$table_name.' ('.implode(', ',$params).') VALUES ('.implode(', ',$values).')';
+            $result = self::query($sql);
             //error_log($sql);
             if ($show_query) {
             	//var_dump($sql);
                 error_log($sql);
             }
-            if (!$result) {                
-                error_log("Error in query: $sql");                
+            if (!$result) {
+                error_log("Error in query: $sql");
             }
             return self::get_last_insert_id();
         }
@@ -1147,14 +1147,14 @@ class Database {
     /**
      * Experimental useful database finder
      * @todo lot of stuff to do here
-     * @todo known issues, it doesn't work when using LIKE conditions 
+     * @todo known issues, it doesn't work when using LIKE conditions
      * @example array('where'=> array('course_code LIKE "?%"'))
      * @example array('where'=> array('type = ? AND category = ?' => array('setting', 'Plugins'))
      * @example array('where'=> array('name = "Julio" AND lastname = "montoya"))
     */
-    public static function select($columns, $table_name, $conditions = array(), $type_result = 'all', $option = 'ASSOC') {        
+    public static function select($columns, $table_name, $conditions = array(), $type_result = 'all', $option = 'ASSOC') {
         $conditions = self::parse_conditions($conditions);
-        
+
         //@todo we could do a describe here to check the columns ...
         $clean_columns = '';
         if (is_array($columns)) {
@@ -1168,10 +1168,10 @@ class Database {
         }
         $sql = "SELECT $clean_columns FROM $table_name $conditions";
         //var_dump($sql);
-                
+
         $result = self::query($sql);
         $array = array();
-        
+
         if ($type_result == 'all') {
             while ($row = self::fetch_array($result, $option)) {
                 if (isset($row['id'])) {
@@ -1192,31 +1192,31 @@ class Database {
      * @param array
      * @todo lot of stuff to do here
     */
-    static function parse_conditions($conditions) {        
+    static function parse_conditions($conditions) {
         if (empty($conditions)) {
             return '';
         }
-        $return_value = $where_return = '';    
-        foreach ($conditions as $type_condition => $condition_data) {       
+        $return_value = $where_return = '';
+        foreach ($conditions as $type_condition => $condition_data) {
             if ($condition_data == false) {
                 continue;
             }
             $type_condition = strtolower($type_condition);
             switch ($type_condition) {
-                case 'where':                    
-                    foreach ($condition_data as $condition => $value_array) {                       
+                case 'where':
+                    foreach ($condition_data as $condition => $value_array) {
                         if (is_array($value_array)) {
-                            $clean_values = array();                       
+                            $clean_values = array();
                             foreach($value_array as $item) {
                                 $item = Database::escape_string($item);
                                 $clean_values[]= $item;
                             }
                         } else {
                             $value_array = Database::escape_string($value_array);
-                            $clean_values = $value_array;                            
+                            $clean_values = $value_array;
                         }
 
-                        if (!empty($condition) && $clean_values != '') {                                                                                      
+                        if (!empty($condition) && $clean_values != '') {
                             $condition = str_replace('%',"'@percentage@'", $condition); //replace "%"
                             $condition = str_replace("'?'","%s", $condition);
                             $condition = str_replace("?","%s", $condition);
@@ -1225,25 +1225,25 @@ class Database {
                             $condition = str_replace("%s","'%s'", $condition);
                             $condition = str_replace("@-@","@%s@", $condition);
 
-                            //Treat conditons as string                            
-                            $condition = vsprintf($condition, $clean_values);                                                        
-                            $condition = str_replace('@percentage@','%', $condition); //replace "%"                            
+                            //Treat conditons as string
+                            $condition = vsprintf($condition, $clean_values);
+                            $condition = str_replace('@percentage@','%', $condition); //replace "%"
                             $where_return .= $condition;
-                        }                       
+                        }
                     }
-                                         
-                        
+
+
                     if (!empty($where_return)) {
                         $return_value = " WHERE $where_return" ;
                     }
                     break;
-                case 'order':                    
+                case 'order':
                     $order_array = $condition_data;
-                    
+
                     if (!empty($order_array)) {
                         // 'order' => 'id desc, name desc'
                         $order_array = self::escape_string($order_array);
-                        $new_order_array = explode(',', $order_array);                            
+                        $new_order_array = explode(',', $order_array);
                         $temp_value = array();
 
                         foreach($new_order_array as $element) {
@@ -1256,25 +1256,25 @@ class Database {
                                 $order = 'DESC';
                                 if (in_array($element[1], array('desc', 'asc'))) {
                                     $order = $element[1];
-                                }                            
-                                $temp_value[]= $element[0].' '.$order.' ';                                       
+                                }
+                                $temp_value[]= $element[0].' '.$order.' ';
                             } else {
                                 //by default DESC
-                                $temp_value[]= $element[0].' DESC ';                                       
+                                $temp_value[]= $element[0].' DESC ';
                             }
                         }
                         if (!empty($temp_value)) {
-                            $return_value .= ' ORDER BY '.implode(', ', $temp_value);                                
+                            $return_value .= ' ORDER BY '.implode(', ', $temp_value);
                         } else {
                             //$return_value .= '';
-                        }                        
-                    }                    
+                        }
+                    }
                     break;
                 case 'limit':
                     $limit_array = explode(',', $condition_data);
-                    
+
                     if (!empty($limit_array)) {
-                        if (count($limit_array) > 1) {                            
+                        if (count($limit_array) > 1) {
                             $return_value .= ' LIMIT '.intval($limit_array[0]).' , '.intval($limit_array[1]);
                         }  else {
                             $return_value .= ' LIMIT '.intval($limit_array[0]);
@@ -1309,7 +1309,7 @@ class Database {
     /**
      * Experimental useful database update
      * @param	string	table name use Database::get_main_table
-     * @param	array	array with values to updates, keys are the fields in the database: Example: $params['name'] = 'Julio'; $params['lastname'] = 'Montoya'; 
+     * @param	array	array with values to updates, keys are the fields in the database: Example: $params['name'] = 'Julio'; $params['lastname'] = 'Montoya';
      * @param	array	where conditions i.e array('id = ?' =>'4')
      * @todo lot of stuff to do here
      */
@@ -1320,9 +1320,9 @@ class Database {
             //Cleaning attributes
             $count = 1;
             foreach ($attributes as $key=>$value) {
-                
+
                 if (!is_array($value))
-                    
+
                 $value = self::escape_string($value);
                 $update_sql .= "$key = '$value' ";
                 if ($count < count($attributes)) {
@@ -1332,7 +1332,7 @@ class Database {
             }
             if (!empty($update_sql)) {
                 //Parsing and cleaning the where conditions
-                $where_return = self::parse_where_conditions($where_conditions);                
+                $where_return = self::parse_where_conditions($where_conditions);
                 $sql    = "UPDATE $table_name SET $update_sql $where_return ";
                 if ($show_query) { var_dump($sql); }
                 $result = self::query($sql);
@@ -1341,7 +1341,7 @@ class Database {
             }
         }
         return false;
-    }    
+    }
 
      /*
         DEPRECATED METHODS

+ 7 - 4
main/inc/lib/display.lib.php

@@ -1136,16 +1136,19 @@ class Display {
                 // If it's a survey, make sure the user's invited. Otherwise drop it.
                 if ($item_property['tool'] == TOOL_SURVEY) {
                     $survey_info = survey_manager::get_survey($item_property['ref'], 0, $course_code);
-                    $invited_users = SurveyUtil::get_invited_users($survey_info['code'], $course_code);
-                    if (!in_array($user_id, $invited_users['course_users'])) continue;
+                    if ($survey_info) {
+                        $invited_users = SurveyUtil::get_invited_users($survey_info['code'], $course_code);
+                        if (!in_array($user_id, $invited_users['course_users'])) {
+                            continue;
+                        }
+                    }
                 }
                 // If it's a learning path, ensure it is currently visible to the user
                 if ($item_property['tool'] == TOOL_LEARNPATH) {
                     require_once api_get_path(SYS_CODE_PATH).'newscorm/learnpath.class.php';
-                    if (!learnpath::is_lp_visible_for_student($item_property['ref'],$user_id, $course_code)) {
+                    if (!learnpath::is_lp_visible_for_student($item_property['ref'], $user_id, $course_code)) {
                         continue;
                     }
-
                 }
                 $notifications[$item_property['tool']] = $item_property;
             }

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

@@ -720,10 +720,14 @@ class GroupManager {
 	 * @param int $group_id The group
          * @return array list of user id
 	 */
-	public static function get_users($group_id, $load_extra_info = false) {
+	public static function get_users($group_id, $load_extra_info = false, $course_id = null) {
 		$group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
 		$group_id = Database::escape_string($group_id);
-		$course_id = api_get_course_int_id();
+        if (empty($course_id)) {
+            $course_id = api_get_course_int_id();
+        } else {
+            $course_id = intval($course_id);
+        }
 		$sql = "SELECT user_id FROM $group_user_table WHERE c_id = $course_id AND group_id = $group_id";
 		$res = Database::query($sql);
 		$users = array ();

+ 4 - 5
main/tracking/courseLog.php

@@ -114,9 +114,6 @@ $htmlHeadXtra[] = "<style type='text/css'>
 div#reporting_table table th {
   vertical-align:top;
 }
-</style>
-<style media='print' type='text/css'>
-
 </style>";
 $htmlHeadXtra[] .= $js;
 
@@ -172,11 +169,13 @@ if (isset($_GET['additional_profile_field']) && is_numeric($_GET['additional_pro
 
 echo '<div class="actions">';
 
-echo Display::return_icon('user_na.png', get_lang('StudentsTracking'), array(), 32);
-echo Display::url(Display::return_icon('course.png', get_lang('CourseTracking'), array(), 32), 'course_log_tools.php?'.api_get_cidreq());
+echo Display::url(Display::return_icon('user_na.png', get_lang('StudentsTracking'), array(), 32), '#');
+echo Display::url(Display::return_icon('group.png', get_lang('GroupReporting'), array(), 32), 'course_log_groups.php?'.api_get_cidreq());
+echo Display::url(Display::return_icon('course.png', get_lang('CourseTracking'), array(), 32), 'course_log_tools.php?'.api_get_cidreq(true, false));
 echo Display::url(Display::return_icon('tools.png', get_lang('ResourcesTracking'), array(), 32), 'course_log_resources.php?'.api_get_cidreq());
 echo Display::url(Display::return_icon('quiz.png', get_lang('ExamTracking'), array(), 32), api_get_path(WEB_CODE_PATH).'tracking/exams.php?'.api_get_cidreq());
 
+
 echo '<span style="float:right; padding-top:0px;">';
 echo '<a href="javascript: void(0);" onclick="javascript: window.print();">'.Display::return_icon('printer.png', get_lang('Print'),'',ICON_SIZE_MEDIUM).'</a>';
 

+ 88 - 0
main/tracking/course_log_groups.php

@@ -0,0 +1,88 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ * 	@package chamilo.tracking
+ */
+// Language files that need to be included.
+$language_file = array('admin', 'tracking', 'scorm', 'exercice');
+
+// Including the global initialization file
+require_once '../inc/global.inc.php';
+
+
+$from_myspace = false;
+$from = isset($_GET['from']) ? $_GET['from'] : null;
+
+if ($from == 'myspace') {
+    $from_myspace = true;
+    $this_section = "session_my_space";
+} else {
+    $this_section = SECTION_COURSES;
+}
+
+// Access restrictions.
+$is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
+
+if (!$is_allowedToTrack) {
+    api_not_allowed();
+    exit;
+}
+
+$course_id = api_get_course_int_id();
+$course_code = api_get_course_id();
+
+
+//jqgrid will use this URL to do the selects
+$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_group_reporting&course_id='.$course_id;
+
+//The order is important you need to check the the $column variable in the model.ajax.php file
+$columns = array(
+    get_lang('Name'), get_lang('Time'), get_lang('Progress'), get_lang('Score'), get_lang('Works'), get_lang('Messages'), get_lang('Actions')
+);
+
+//Column config
+$column_model = array(
+    array('name' => 'name', 'index' => 'name', 'width' => '200', 'align' => 'left'),
+    array('name' => 'time', 'index' => 'time', 'width' => '50', 'align' => 'left', 'sortable' => 'false'),
+    array('name' => 'progress', 'index' => 'progress', 'width' => '50', 'align' => 'left', 'sortable' => 'false'),
+    array('name' => 'score', 'index' => 'score', 'width' => '50', 'align' => 'left', 'sortable' => 'false'),
+    array('name' => 'works', 'index' => 'works', 'width' => '50', 'align' => 'left', 'sortable' => 'false'),
+    array('name' => 'messages', 'index' => 'messages', 'width' => '50', 'align' => 'left', 'sortable' => 'false'),
+    array('name' => 'actions', 'index' => 'actions', 'width' => '50', 'align' => 'left', 'formatter' => 'action_formatter', 'sortable' => 'false')
+);
+
+//Autowidth
+$extra_params['autowidth'] = 'true';
+//height auto
+$extra_params['height'] = 'auto';
+
+$action_links = '
+function action_formatter(cellvalue, options, rowObject) {
+    return \'<a href="course_log_tools.php?id_session=0&cidReq='.$course_code.'&gidReq=\'+options.rowId+\'">'.Display::return_icon('2rightarrow.gif',get_lang('Edit'),'',ICON_SIZE_SMALL).'</a>'.
+    '\';
+}';
+
+
+//Add the JS needed to use the jqgrid
+$htmlHeadXtra[] = api_get_jqgrid_js();
+
+$htmlHeadXtra[] = '
+<script>
+$(function() {
+    '.Display::grid_js('group_users',$url, $columns, $column_model, $extra_params, array(), $action_links, true).'
+});
+</script>';
+
+Display::display_header();
+
+echo '<div class="actions">';
+echo Display::url(Display::return_icon('user.png', get_lang('StudentsTracking'), array(), 32), 'courseLog.php?'.api_get_cidreq(true, false));
+echo Display::url(Display::return_icon('group_na.png', get_lang('GroupReporting'), array(), 32), '#');
+echo Display::url(Display::return_icon('course.png', get_lang('CourseTracking'), array(), 32), 'course_log_tools.php?'.api_get_cidreq(true, false));
+echo Display::url(Display::return_icon('tools.png', get_lang('ResourcesTracking'), array(), 32), 'course_log_resources.php?'.api_get_cidreq(true, false));
+echo '</div>';
+
+echo Display::grid_html('group_users');
+
+Display::display_footer();

+ 5 - 4
main/tracking/course_log_resources.php

@@ -27,7 +27,7 @@ $from = isset($_GET['from']) ? $_GET['from'] : null;
 
 if ($from == 'myspace') {
     $from_myspace = true;
-    $this_section = "session_my_space";    
+    $this_section = "session_my_space";
 } else {
     $this_section = SECTION_COURSES;
 }
@@ -35,8 +35,8 @@ if ($from == 'myspace') {
 // Access restrictions.
 $is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
 
-if (!$is_allowedToTrack) {    
-    api_not_allowed();    
+if (!$is_allowedToTrack) {
+    api_not_allowed();
     exit;
 }
 
@@ -79,7 +79,8 @@ Display::display_header($nameTools, 'Tracking');
 /* MAIN CODE */
 
 echo '<div class="actions">';
-echo Display::url(Display::return_icon('user.png', get_lang('StudentsTracking'), array(), 32), 'courseLog.php?'.api_get_cidreq());  
+echo Display::url(Display::return_icon('user.png', get_lang('StudentsTracking'), array(), 32), 'courseLog.php?'.api_get_cidreq());
+echo Display::url(Display::return_icon('group.png', get_lang('GroupReporting'), array(), 32),  'course_log_groups.php?'.api_get_cidreq(true, false));
 echo Display::url(Display::return_icon('course.png', get_lang('CourseTracking'), array(), 32), 'course_log_tools.php?'.api_get_cidreq());
 echo Display::return_icon('tools_na.png', get_lang('ResourcesTracking'), array(), 32);
 echo '<span style="float:right; padding-top:0px;">';

+ 70 - 39
main/tracking/course_log_tools.php

@@ -7,8 +7,6 @@
 
 /* INIT SECTION */
 
-$pathopen = isset($_REQUEST['pathopen']) ? $_REQUEST['pathopen'] : null;
-
 // Language files that need to be included.
 $language_file = array('admin', 'tracking', 'scorm', 'exercice');
 
@@ -23,7 +21,7 @@ $from = isset($_GET['from']) ? $_GET['from'] : null;
 
 if ($from == 'myspace') {
     $from_myspace = true;
-    $this_section = "session_my_space";    
+    $this_section = "session_my_space";
 } else {
     $this_section = SECTION_COURSES;
 }
@@ -31,8 +29,8 @@ if ($from == 'myspace') {
 // Access restrictions.
 $is_allowedToTrack = api_is_platform_admin() || api_is_allowed_to_create_course() || api_is_session_admin() || api_is_drh() || api_is_course_tutor();
 
-if (!$is_allowedToTrack) {    
-    api_not_allowed();    
+if (!$is_allowedToTrack) {
+    api_not_allowed(true);
     exit;
 }
 
@@ -49,7 +47,7 @@ require_once api_get_path(SYS_CODE_PATH).'resourcelinker/resourcelinker.inc.php'
 require_once api_get_path(SYS_CODE_PATH).'survey/survey.lib.php';
 require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php';
 
-$TABLEQUIZ              = Database::get_course_table(TABLE_QUIZ_TEST);
+$TABLEQUIZ = Database::get_course_table(TABLE_QUIZ_TEST);
 
 // Starting the output buffering when we are exporting the information.
 $export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
@@ -61,6 +59,8 @@ if ($export_csv) {
     }
     ob_start();
 }
+
+$group_id = api_get_group_id();
 $csv_content = array();
 
 // Breadcrumbs.
@@ -77,12 +77,12 @@ $nameTools = get_lang('Tracking');
 Display::display_header($nameTools, 'Tracking');
 
 // getting all the students of the course
-if (empty($session_id)) {	
+if (empty($session_id)) {
 	// Registered students in a course outside session.
-	$a_students = CourseManager :: get_student_list_from_course_code(api_get_course_id());	
+	$a_students = CourseManager :: get_student_list_from_course_code(api_get_course_id(), false, 0, api_get_group_id());
 } else {
 	// Registered students in session.
-	$a_students = CourseManager :: get_student_list_from_course_code(api_get_course_id(), true, api_get_session_id());    
+	$a_students = CourseManager :: get_student_list_from_course_code(api_get_course_id(), true, api_get_session_id());
 }
 
 $nbStudents = count($a_students);
@@ -91,16 +91,23 @@ $nbStudents = count($a_students);
 /* MAIN CODE */
 
 echo '<div class="actions">';
+echo Display::url(Display::return_icon('user.png', get_lang('StudentsTracking'), array(), 32), 'courseLog.php?'.api_get_cidreq());
+
+if (empty($group_id)) {
+    echo Display::url(Display::return_icon('group.png', get_lang('GroupReporting'), array(), 32),  'course_log_groups.php?'.api_get_cidreq());
+    echo Display::url(Display::return_icon('course_na.png', get_lang('CourseTracking'), array(), 32), '#');
+} else {
+    echo Display::url(Display::return_icon('group_na.png', get_lang('GroupReporting'), array(), 32),  '#');
+    echo Display::url(Display::return_icon('course.png', get_lang('CourseTracking'), array(), 32), 'course_log_tools.php?'.api_get_cidreq(true, false).'&gidReq=0');
+}
 
-echo Display::url(Display::return_icon('user.png', get_lang('StudentsTracking'), array(), 32), 'courseLog.php?'.api_get_cidreq());        
-echo Display::return_icon('course_na.png', get_lang('CourseTracking'), array(), 32);
-echo Display::url(Display::return_icon('tools.png', get_lang('ResourcesTracking'), array(), 32), 'course_log_resources.php?'.api_get_cidreq());        
+echo Display::url(Display::return_icon('tools.png', get_lang('ResourcesTracking'), array(), 32), 'course_log_resources.php?'.api_get_cidreq());
 
 echo '<span style="float:right; padding-top:0px;">';
 echo '<a href="javascript: void(0);" onclick="javascript: window.print();">'.Display::return_icon('printer.png', get_lang('Print'),'',ICON_SIZE_MEDIUM).'</a>';
 
 echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&id_session='.api_get_session_id().'&export=csv">
-	'.Display::return_icon('export_csv.png', get_lang('ExportAsCSV'),'',ICON_SIZE_MEDIUM).'</a>';	
+	'.Display::return_icon('export_csv.png', get_lang('ExportAsCSV'),'',ICON_SIZE_MEDIUM).'</a>';
 
 echo '</span>';
 echo '</div>';
@@ -110,15 +117,22 @@ $course_code = api_get_course_id();
 $list = new LearnpathList(null, $course_code, $session_id);
 
 $flat_list = $list->get_flat_list();
-    
-    
+
+
 if (count($flat_list) > 0) {
+    $group_name = null;
+    if ($group_id) {
+        $group_info = GroupManager::get_group_properties($group_id);
+        $group_name = " - ".get_lang('Group').": ".$group_info['name'];
+    }
+    echo Display::page_subheader2(get_lang('Course').": ".$course_info['title'].$group_name);
+
 
     // learning path tracking
     echo '<div class="report_section">
-            '.Display::page_subheader(Display::return_icon('scorms.gif',get_lang('AverageProgressInLearnpath')).get_lang('AverageProgressInLearnpath')).'
+            '.Display::page_subheader2(Display::return_icon('scorms.gif',get_lang('AverageProgressInLearnpath')).get_lang('AverageProgressInLearnpath')).'
             <table class="data_table">';
-    
+
     if ($export_csv) {
         $temp = array(get_lang('AverageProgressInLearnpath', ''), '');
         $csv_content[] = array('', '');
@@ -129,7 +143,7 @@ if (count($flat_list) > 0) {
         $lp_avg_progress = 0;
         foreach ($a_students as $student_id => $student) {
             // get the progress in learning pathes
-            $lp_avg_progress += Tracking::get_avg_student_progress($student_id, $course_code, array($lp_id), $session_id);                
+            $lp_avg_progress += Tracking::get_avg_student_progress($student_id, $course_code, array($lp_id), $session_id);
         }
         if ($nbStudents > 0) {
             $lp_avg_progress = $lp_avg_progress / $nbStudents;
@@ -149,21 +163,22 @@ if (count($flat_list) > 0) {
         }
     }
     echo '</table></div>';
-} else {        
+} else {
     if ($export_csv) {
         $temp = array(get_lang('NoLearningPath', ''), '');
         $csv_content[] = $temp;
     }
-}   
+}
 
 // Exercices tracking.
 echo '<div class="report_section">
-           '.Display::page_subheader(Display::return_icon('quiz.gif',get_lang('AverageResultsToTheExercices')).get_lang('AverageResultsToTheExercices')).'
+           '.Display::page_subheader2(Display::return_icon('quiz.gif',get_lang('AverageResultsToTheExercices')).get_lang('AverageResultsToTheExercices')).'
         <table class="data_table">';
 
 $course_id = api_get_course_int_id();
 
-$sql = "SELECT id, title FROM $TABLEQUIZ 
+//@todo user $exercise = new Exercise($course_id);
+$sql = "SELECT id, title FROM $TABLEQUIZ
         WHERE c_id = $course_id AND active <> -1 AND session_id = $session_id";
 $rs = Database::query($sql);
 
@@ -182,7 +197,7 @@ if (Database::num_rows($rs) > 0) {
         $quiz_avg_score = 0;
         if ($count_students > 0) {
             foreach ($student_ids as $student_id) {
-                $avg_student_score = Tracking::get_avg_student_exercise_score($student_id, $course_code, $quiz['id'], $session_id);                    
+                $avg_student_score = Tracking::get_avg_student_exercise_score($student_id, $course_code, $quiz['id'], $session_id);
                 $quiz_avg_score += $avg_student_score;
             }
         }
@@ -202,24 +217,38 @@ if (Database::num_rows($rs) > 0) {
         $temp = array(get_lang('NoExercises', ''), '');
         $csv_content[] = $temp;
     }
-}    
+}
 echo '</table></div>';
 echo '<div class="clear"></div>';
 
 // Forums tracking.
 echo '<div class="report_section">
-        '.Display::page_subheader(Display::return_icon('forum.gif', get_lang('Forum')).get_lang('Forum').'&nbsp;-&nbsp;<a href="../forum/index.php?cidReq='.$_course['id'].'">'.get_lang('SeeDetail').'</a>').
+        '.Display::page_subheader2(Display::return_icon('forum.gif', get_lang('Forum')).get_lang('Forum').'&nbsp;-&nbsp;<a href="../forum/index.php?cidReq='.$_course['id'].'">'.get_lang('SeeDetail').'</a>').
         '<table class="data_table">';
-$count_number_of_posts_by_course    = Tracking :: count_number_of_posts_by_course($course_code, $session_id);
-$count_number_of_forums_by_course   = Tracking :: count_number_of_forums_by_course($course_code, $session_id);
-$count_number_of_threads_by_course  = Tracking :: count_number_of_threads_by_course($course_code, $session_id);
+
+$filter_by_users = array();
+if (!empty($group_id)) {
+    $filter_by_users = $student_ids;
+}
+$count_number_of_posts_by_course    = Tracking :: count_number_of_posts_by_course($course_code, $session_id, $filter_by_users);
+$count_number_of_forums_by_course = 0;
+if (empty($group_id)) {
+    $count_number_of_forums_by_course   = Tracking :: count_number_of_forums_by_course($course_code, $session_id, $filter_by_users);
+}
+
+$count_number_of_threads_by_course  = Tracking :: count_number_of_threads_by_course($course_code, $session_id, $filter_by_users);
 if ($export_csv) {
     $csv_content[] = array(get_lang('Forum'), '');
-    $csv_content[] = array(get_lang('ForumForumsNumber', ''), $count_number_of_forums_by_course);
+    if (empty($group_id)) {
+        $csv_content[] = array(get_lang('ForumForumsNumber', ''), $count_number_of_forums_by_course);
+    }
     $csv_content[] = array(get_lang('ForumThreadsNumber', ''), $count_number_of_threads_by_course);
     $csv_content[] = array(get_lang('ForumPostsNumber', ''), $count_number_of_posts_by_course);
 }
-echo '<tr><td>'.get_lang('ForumForumsNumber').'</td><td align="right">'.$count_number_of_forums_by_course.'</td></tr>';
+if (empty($group_id)) {
+    echo '<tr><td>'.get_lang('ForumForumsNumber').'</td><td align="right">'.$count_number_of_forums_by_course.'</td></tr>';
+}
+
 echo '<tr><td>'.get_lang('ForumThreadsNumber').'</td><td align="right">'.$count_number_of_threads_by_course.'</td></tr>';
 echo '<tr><td>'.get_lang('ForumPostsNumber').'</td><td align="right">'.$count_number_of_posts_by_course.'</td></tr>';
 echo '</table></div>';
@@ -228,9 +257,10 @@ echo '<div class="clear"></div>';
 // Chat tracking.
 
 echo '<div class="report_section">
-        '.Display::page_subheader(Display::return_icon('chat.gif',get_lang('Chat')).get_lang('Chat')).'
+        '.Display::page_subheader2(Display::return_icon('chat.gif',get_lang('Chat')).get_lang('Chat')).'
         <table class="data_table">';
-$chat_connections_during_last_x_days_by_course = Tracking::chat_connections_during_last_x_days_by_course($course_code, 7, $session_id);
+
+$chat_connections_during_last_x_days_by_course = Tracking::chat_connections_during_last_x_days_by_course($course_code, 7, $session_id, $filter_by_users);
 if ($export_csv) {
     $csv_content[] = array(get_lang('Chat', ''), '');
     $csv_content[] = array(sprintf(get_lang('ChatConnectionsDuringLastXDays', ''), '7'), $chat_connections_during_last_x_days_by_course);
@@ -242,10 +272,10 @@ echo '<div class="clear"></div>';
 
 // Tools tracking.
 echo '<div class="report_section">
-            '.Display::page_subheader(Display::return_icon('acces_tool.gif', get_lang('ToolsMostUsed')).get_lang('ToolsMostUsed')).'
+            '.Display::page_subheader2(Display::return_icon('acces_tool.gif', get_lang('ToolsMostUsed')).get_lang('ToolsMostUsed')).'
         <table class="data_table">';
 
-$tools_most_used = Tracking::get_tools_most_used_by_course($course_code, $session_id);    
+$tools_most_used = Tracking::get_tools_most_used_by_course($course_code, $session_id, $filter_by_users);
 
 if ($export_csv) {
     $temp = array(get_lang('ToolsMostUsed'), '');
@@ -278,10 +308,11 @@ if (!isset($_GET['num']) || empty($_GET['num'])) {
 }
 
  echo '<a name="documents_tracking" id="a"></a><div class="report_section">
-            '.Display::page_subheader(Display::return_icon('documents.gif',get_lang('DocumentsMostDownloaded')).'&nbsp;'.get_lang('DocumentsMostDownloaded').$link).'
+            '.Display::page_subheader2(Display::return_icon('documents.gif',get_lang('DocumentsMostDownloaded')).'&nbsp;'.get_lang('DocumentsMostDownloaded').$link).'
         <table class="data_table">';
 
-$documents_most_downloaded = Tracking::get_documents_most_downloaded_by_course($course_code, $session_id, $num);
+//No group id
+$documents_most_downloaded = Tracking::get_documents_most_downloaded_by_course($course_code, $session_id, $num, $filter_by_users);
 
 if ($export_csv) {
     $temp = array(get_lang('DocumentsMostDownloaded', ''), '');
@@ -289,7 +320,7 @@ if ($export_csv) {
     $csv_content[] = $temp;
 }
 
-if (!empty($documents_most_downloaded)) {        
+if (!empty($documents_most_downloaded)) {
     foreach ($documents_most_downloaded as $row) {
         echo '<tr>
                 <td>'.Display::url($row['down_doc_path'], api_get_path(WEB_CODE_PATH).'document/show_content.php?file='.$row['down_doc_path'].$course_path_params).'</td>
@@ -313,10 +344,10 @@ echo '<div class="clear"></div>';
 
 // links tracking
  echo '<div class="report_section">
-            '.Display::page_subheader(Display::return_icon('link.gif',get_lang('LinksMostClicked')).'&nbsp;'.get_lang('LinksMostClicked')).'
+            '.Display::page_subheader2(Display::return_icon('link.gif',get_lang('LinksMostClicked')).'&nbsp;'.get_lang('LinksMostClicked')).'
         <table class="data_table">';
 
-$links_most_visited = Tracking::get_links_most_visited_by_course($course_code, $session_id);
+$links_most_visited = Tracking::get_links_most_visited_by_course($course_code, $session_id, $filter_by_users);
 
 if ($export_csv) {
     $temp = array(get_lang('LinksMostClicked'), '');