Browse Source

Merge pull request #19 from chamilo/1.9.x

1.9.x
ycastillo 11 years ago
parent
commit
cbb12df535

+ 337 - 0
main/admin/access_url_edit_course_category_to_url.php

@@ -0,0 +1,337 @@
+<?php
+/* For licensing terms, see /license.txt */
+/**
+*	@package chamilo.admin
+*	@author Julio Montoya <gugli100@gmail.com>
+*/
+
+// name of the language file that needs to be included
+$language_file = 'admin';
+
+// resetting the course id
+$cidReset = true;
+
+require_once '../inc/global.inc.php';
+require_once api_get_path(LIBRARY_PATH).'urlmanager.lib.php';
+require_once api_get_path(LIBRARY_PATH).'course_category.lib.php';
+require_once api_get_path(LIBRARY_PATH).'xajax/xajax.inc.php';
+
+$xajax = new xajax();
+$xajax->registerFunction(array('searchCourseCategoryAjax', 'UrlManager', 'searchCourseCategoryAjax'));
+
+// Setting the section (for the tabs)
+$this_section = SECTION_PLATFORM_ADMIN;
+
+// Access restrictions
+api_protect_global_admin_script();
+if (!api_get_multiple_access_url()) {
+    header('Location: index.php');
+    exit;
+}
+
+// Setting breadcrumbs
+$tool_name = get_lang('EditUserGroupToURL');
+$interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));
+$interbreadcrumb[] = array ('url' => 'access_urls.php', 'name' => get_lang('MultipleAccessURLs'));
+
+$add_type = 'multiple';
+if (isset($_REQUEST['add_type']) && $_REQUEST['add_type'] != '') {
+    $add_type = Security::remove_XSS($_REQUEST['add_type']);
+}
+
+$access_url_id = 1;
+if (isset($_REQUEST['access_url_id']) && $_REQUEST['access_url_id'] != '') {
+    $access_url_id = Security::remove_XSS($_REQUEST['access_url_id']);
+}
+
+$xajax->processRequests();
+$htmlHeadXtra[] = $xajax->getJavascript('../inc/lib/xajax/');
+$htmlHeadXtra[] = '
+<script>
+function add_user_to_url(code, content) {
+
+	document.getElementById("course_to_add").value = "";
+	document.getElementById("ajax_list_courses").innerHTML = "";
+
+	destination = document.getElementById("destination_users");
+	destination.options[destination.length] = new Option(content,code);
+
+	destination.selectedIndex = -1;
+	sortOptions(destination.options);
+}
+
+function send() {
+
+	if (document.formulaire.access_url_id.value!=0) {
+		document.formulaire.form_sent.value=0;
+		document.formulaire.add_type.value=\''.$add_type.'\';
+		document.formulaire.submit();
+	}
+}
+
+function remove_item(origin) {
+	for(var i = 0 ; i<origin.options.length ; i++) {
+		if(origin.options[i].selected) {
+			origin.options[i]=null;
+			i = i-1;
+		}
+	}
+}
+</script>';
+
+$form_sent=0;
+$errorMsg='';
+$UserList=$SessionList = array();
+$users=$sessions = array();
+
+if (isset($_POST['form_sent']) && $_POST['form_sent']) {
+    $form_sent = $_POST['form_sent'];
+    $list = $_POST['course_list'];
+
+    if (!is_array($list)) {
+        $list = array();
+    }
+
+    if ($form_sent == 1) {
+        if ($access_url_id == 0) {
+            header('Location: access_url_edit_users_to_url.php?action=show_message&message='.get_lang('SelectURL'));
+        } elseif (is_array($list)) {
+            UrlManager::updateUrlRelCourseCategory($list, $access_url_id);
+            header('Location: access_urls.php?action=show_message&message='.get_lang('Updated'));
+        }
+        exit;
+    }
+}
+
+Display::display_header($tool_name);
+
+api_display_tool_title($tool_name);
+
+if ($_GET['action'] == 'show_message') {
+    Display :: display_normal_message(Security::remove_XSS(stripslashes($_GET['message'])));
+}
+
+$noUserGroupList = $userGroupList = array();
+$ajax_search = $add_type == 'unique' ? true : false;
+
+if ($ajax_search) {
+    $userGroups = UrlManager::getUrlRelCourseCategory($access_url_id);
+    foreach ($userGroups as $item) {
+        $userGroupList[$item['id']] = $item;
+    }
+} else {
+    $userGroups = UrlManager::getUrlRelCourseCategory();
+
+    foreach ($userGroups as $item) {
+        if ($item['access_url_id'] == $access_url_id) {
+            $userGroupList[$item['id']] = $item ;
+        }
+    }
+    $noUserGroupList = getCourseCategoryNotInList(array_keys($userGroupList));
+}
+
+if ($add_type == 'multiple') {
+	$link_add_type_unique = '<a href="'.api_get_self().'?add_type=unique&access_url_id='.$access_url_id.'">'.get_lang('SessionAddTypeUnique').'</a>';
+	$link_add_type_multiple = get_lang('SessionAddTypeMultiple');
+} else {
+	$link_add_type_unique = get_lang('SessionAddTypeUnique');
+	$link_add_type_multiple = '<a href="'.api_get_self().'?add_type=multiple&access_url_id='.$access_url_id.'">'.get_lang('SessionAddTypeMultiple').'</a>';
+}
+
+$url_list = UrlManager::get_url_data();
+?>
+<div style="text-align: left;">
+	<?php echo $link_add_type_unique ?>&nbsp;|&nbsp;<?php echo $link_add_type_multiple ?>
+</div>
+<br /><br />
+<form
+    name="formulaire"
+    method="post"
+    action="<?php echo api_get_self(); ?>"
+    style="margin:0px;" <?php if ($ajax_search) { echo ' onsubmit="valide();"'; } ?>
+>
+<?php echo get_lang('SelectUrl').' : '; ?>
+<select name="access_url_id" onchange="javascript:send();">
+<option value="0">-- <?php echo get_lang('SelectUrl')?> -- </option>
+	<?php
+    $url_selected = '';
+    foreach ($url_list as $url_obj) {
+        $checked = '';
+        if (!empty($access_url_id)) {
+            if ($url_obj[0] == $access_url_id) {
+                $checked = 'selected=true';
+                $url_selected=$url_obj[1];
+            }
+        }
+        if ($url_obj['active']==1) { ?>
+            <option <?php echo $checked;?> value="<?php echo $url_obj[0]; ?>"> <?php echo $url_obj[1]; ?>
+            </option>
+        <?php
+        }
+    }
+?>
+</select>
+<br /><br />
+<input type="hidden" name="form_sent" value="1" />
+<input type="hidden" name="add_type" value = "<?php echo $add_type ?>" />
+
+<?php
+if (!empty($errorMsg)) {
+    Display::display_normal_message($errorMsg); //main API
+}
+?>
+
+<table border="0" cellpadding="5" cellspacing="0" width="100%">
+<!-- Users -->
+<tr>
+  <td align="center"><b><?php echo get_lang('CourseCategoryInPlatform') ?> :</b>
+  </td>
+  <td></td>
+  <td align="center"><b><?php echo get_lang('CourseCategoryListIn').' '.$url_selected; ?></b></td>
+</tr>
+
+<tr>
+  <td align="center">
+  <div id="content_source">
+    <?php if ($ajax_search) { ?>
+		<input type="text" id="course_to_add" onkeyup="xajax_searchCourseCategoryAjax(this.value,document.formulaire.access_url_id.options[document.formulaire.access_url_id.selectedIndex].value)" />
+		<div id="ajax_list_courses"></div>
+    <?php } else { ?>
+	  <select id="origin_users" name="no_course_list[]" multiple="multiple" size="15" style="width:380px;">
+		<?php
+		foreach ($noUserGroupList as $noItem) {
+		?>
+			<option value="<?php echo $noItem['id']; ?>">
+                <?php echo $noItem['name']; ?>
+            </option>
+		<?php
+		}
+		?>
+	  </select>
+	<?php
+  	  }
+  	 ?>
+  </div>
+  </td>
+  <td width="10%" valign="middle" align="center">
+  <?php
+  if ($ajax_search) {
+	?>
+	<button class="arrowl" type="button" onclick="remove_item(document.getElementById('destination_users'))" ></button>
+  	<?php
+  } else {
+  	?>
+	<button class="arrowr" type="button" onclick="moveItem(document.getElementById('origin_users'), document.getElementById('destination_users'))" ></button>
+	<br /><br />
+	<button class="arrowl" type="button" onclick="moveItem(document.getElementById('destination_users'), document.getElementById('origin_users'))" ></button>
+	<?php
+  }
+  ?>
+	<br /><br /><br /><br /><br /><br />
+  </td>
+  <td align="center">
+  <select id="destination_users" name="course_list[]" multiple="multiple" size="15" style="width:380px;">
+<?php
+foreach($userGroupList as $item) {
+?>
+	<option value="<?php echo $item['id']; ?>">
+        <?php echo $item['name']; ?>
+    </option>
+<?php
+}
+?>
+  </select>
+  </td>
+</tr>
+<tr>
+	<td colspan="3" align="center">
+		<br />
+		<?php
+		if(isset($_GET['add']))
+			echo '<button class="save" onclick="valide()" >'.get_lang('Add').'</button>';
+		else
+			echo '<button class="save" onclick="valide()" >'.get_lang('Edit').'</button>';
+		?>
+	</td>
+</tr>
+</table>
+</form>
+<script>
+
+function moveItem(origin , destination) {
+	for(var i = 0 ; i<origin.options.length ; i++) {
+		if(origin.options[i].selected) {
+			destination.options[destination.length] = new Option(origin.options[i].text,origin.options[i].value);
+			origin.options[i]=null;
+			i = i-1;
+		}
+	}
+	destination.selectedIndex = -1;
+	sortOptions(destination.options);
+}
+
+function sortOptions(options) {
+	newOptions = new Array();
+	for (i = 0 ; i<options.length ; i++)
+		newOptions[i] = options[i];
+
+	newOptions = newOptions.sort(mysort);
+	options.length = 0;
+	for(i = 0 ; i < newOptions.length ; i++)
+		options[i] = newOptions[i];
+
+}
+
+function mysort(a, b) {
+	if(a.text.toLowerCase() > b.text.toLowerCase()){
+		return 1;
+	}
+	if(a.text.toLowerCase() < b.text.toLowerCase()){
+		return -1;
+	}
+	return 0;
+}
+
+function valide(){
+	var options = document.getElementById('destination_users').options;
+	for (i = 0 ; i<options.length ; i++)
+		options[i].selected = true;
+	document.forms.formulaire.submit();
+}
+
+function loadUsersInSelect(select){
+
+	var xhr_object = null;
+
+	if(window.XMLHttpRequest) // Firefox
+		xhr_object = new XMLHttpRequest();
+	else if(window.ActiveXObject) // Internet Explorer
+		xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
+	else  // XMLHttpRequest non supporté par le navigateur
+	alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
+
+	xhr_object.open("POST", "loadUsersInSelect.ajax.php");
+	xhr_object.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+	nosessionUsers = makepost(document.getElementById('origin_users'));
+	sessionUsers = makepost(document.getElementById('destination_users'));
+	nosessionClasses = makepost(document.getElementById('origin_classes'));
+	sessionClasses = makepost(document.getElementById('destination_classes'));
+	xhr_object.send("nosessionusers="+nosessionUsers+"&sessionusers="+sessionUsers+"&nosessionclasses="+nosessionClasses+"&sessionclasses="+sessionClasses);
+
+	xhr_object.onreadystatechange = function() {
+		if(xhr_object.readyState == 4) {
+			document.getElementById('content_source').innerHTML = result = xhr_object.responseText;
+		}
+	}
+}
+
+function makepost(select){
+	var options = select.options;
+	var ret = "";
+	for (i = 0 ; i<options.length ; i++)
+		ret = ret + options[i].value +'::'+options[i].text+";;";
+	return ret;
+}
+</script>
+<?php
+Display::display_footer();

+ 0 - 5
main/admin/access_url_edit_usergroup_to_url.php

@@ -30,11 +30,6 @@ if (!api_get_multiple_access_url()) {
     exit;
 }
 
-// Database Table Definitions
-$tbl_access_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
-$tbl_course 			 = Database::get_main_table(TABLE_MAIN_COURSE);
-$tbl_access_url 		 = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
-
 // setting breadcrumbs
 $tool_name = get_lang('EditUserGroupToURL');
 $interbreadcrumb[] = array ('url' => 'index.php', 'name' => get_lang('PlatformAdmin'));

+ 14 - 1
main/admin/access_urls.php

@@ -25,6 +25,7 @@ Display :: display_header($tool_name);
 
 require_once api_get_path(LIBRARY_PATH).'urlmanager.lib.php';
 require_once api_get_path(LIBRARY_PATH).'usergroup.lib.php';
+require_once api_get_path(LIBRARY_PATH).'course_category.lib.php';
 
 $my_user_url_list = api_get_access_url_from_user(api_get_user_id());
 $current_access_url_id = api_get_current_access_url_id();
@@ -108,10 +109,22 @@ echo Display::url(Display::return_icon('new_link.png',  get_lang('AddUrl'), arra
 echo Display::url(Display::return_icon('user.png',      get_lang('ManageUsers'), array(), ICON_SIZE_MEDIUM),     api_get_path(WEB_CODE_PATH).'admin/access_url_edit_users_to_url.php');
 echo Display::url(Display::return_icon('course.png',    get_lang('ManageCourses'), array(), ICON_SIZE_MEDIUM),   api_get_path(WEB_CODE_PATH).'admin/access_url_edit_courses_to_url.php');
 //echo Display::url(Display::return_icon('session.png',   get_lang('ManageSessions'), array(), ICON_SIZE_MEDIUM), api_get_path(WEB_CODE_PATH).'admin/access_url_edit_sessions_to_url.php');
+
 $userGroup = new Usergroup();
 if ($userGroup->getUseMultipleUrl()) {
-    echo Display::url(Display::return_icon('class.png',   get_lang('ManageUserGroup'), array(), ICON_SIZE_MEDIUM), api_get_path(WEB_CODE_PATH).'admin/access_url_edit_usergroup_to_url.php');
+    echo Display::url(
+        Display::return_icon('class.png', get_lang('ManageUserGroup'), array(), ICON_SIZE_MEDIUM),
+        api_get_path(WEB_CODE_PATH).'admin/access_url_edit_usergroup_to_url.php'
+    );
+}
+
+if (isMultipleUrlSupport()) {
+    echo Display::url(
+        Display::return_icon('folder.png', get_lang('ManageCourseCategories'), array(), ICON_SIZE_MEDIUM),
+        api_get_path(WEB_CODE_PATH).'admin/access_url_edit_course_category_to_url.php'
+    );
 }
+
 echo '</div>';
 
 //$table = new SortableTable('urls', 'url_count_mask', 'get_url_data_mask',2);

+ 12 - 5
main/admin/course_category.php

@@ -29,7 +29,10 @@ $errorMsg = '';
 if (!empty($action)) {
     if ($action == 'delete') {
         if (api_get_multiple_access_url()) {
-            if (api_get_current_access_url_id() == 1) {
+            if (api_get_current_access_url_id() == 1 ||
+                (isset($_configuration['enable_multiple_url_support_for_course_category']) &&
+                $_configuration['enable_multiple_url_support_for_course_category'])
+            ) {
                 deleteNode($_GET['id']);
                 header('Location: ' . api_get_self() . '?category=' . Security::remove_XSS($category));
                 exit();
@@ -87,8 +90,12 @@ if ($action == 'add' || $action == 'edit') {
         $form->addElement('text', 'name', get_lang("CategoryName"));
         $form->addRule('name', get_lang('PleaseEnterCategoryInfo'), 'required');
         $form->addRule('code', get_lang('PleaseEnterCategoryInfo'), 'required');
-        $form->addElement('radio', 'auth_course_child', get_lang("AllowCoursesInCategory"), get_lang('Yes'), 'TRUE');
-        $form->addElement('radio', 'auth_course_child', null, get_lang('No'), 'FALSE');
+        $group = array(
+            $form->createElement('radio', 'auth_course_child', get_lang("AllowCoursesInCategory"), get_lang('Yes'), 'TRUE'),
+            $form->createElement('radio', 'auth_course_child', null, get_lang('No'), 'FALSE')
+        );
+        $form->addGroup($group, null, get_lang("AllowCoursesInCategory"));
+
         if (!empty($categoryInfo)) {
             $class = "save";
             $text = get_lang('CategoryMod');
@@ -114,7 +121,7 @@ if ($action == 'add' || $action == 'edit') {
         );
     }
 
-    if (empty($parentInfo) || $parentInfo['auth_cat_child'] == 'FALSE') {
+    if (empty($parentInfo) || $parentInfo['auth_cat_child'] == 'TRUE') {
         echo Display::url(
             Display::return_icon('new_folder.png', get_lang("AddACategory"), '', ICON_SIZE_MEDIUM),
             api_get_path(WEB_CODE_PATH).'admin/course_category.php?action=add&category='.$category
@@ -123,7 +130,7 @@ if ($action == 'add' || $action == 'edit') {
 
     echo '</div>';
     if (!empty($parentInfo)) {
-        echo Display::page_subheader($parentInfo['name']);
+        echo Display::page_subheader($parentInfo['name'].' ('.$parentInfo['code'].')');
     }
     echo listCategories($category);
 }

+ 39 - 41
main/admin/dashboard_add_sessions_to_user.php

@@ -11,7 +11,6 @@ $language_file='admin';
 // resetting the course id
 $cidReset = true;
 
-// including some necessary dokeos files
 require_once '../inc/global.inc.php';
 require_once api_get_path(LIBRARY_PATH).'xajax/xajax.inc.php';
 global $_configuration;
@@ -52,8 +51,8 @@ if (UserManager::is_admin($user_id)) {
 }
 
 $add_type = 'multiple';
-if(isset($_GET['add_type']) && $_GET['add_type']!=''){
-	$add_type = Security::remove_XSS($_REQUEST['add_type']);
+if (isset($_GET['add_type']) && $_GET['add_type']!=''){
+    $add_type = Security::remove_XSS($_REQUEST['add_type']);
 }
 
 if (!api_is_platform_admin() && !api_is_session_admin()) {
@@ -61,40 +60,40 @@ if (!api_is_platform_admin() && !api_is_session_admin()) {
 }
 
 function search_sessions($needle,$type) {
-	global $_configuration, $tbl_session_rel_access_url, $tbl_session, $user_id;
-
-	$xajax_response = new XajaxResponse();
-	$return = '';
-	if(!empty($needle) && !empty($type)) {
-		// xajax send utf8 datas... datas in db can be non-utf8 datas
-		$charset = api_get_system_encoding();
-		$needle = api_convert_encoding($needle, $charset, 'utf-8');
-		$assigned_sessions_to_hrm = SessionManager::get_sessions_followed_by_drh($user_id);
-		$assigned_sessions_id = array_keys($assigned_sessions_to_hrm);
-
-		$without_assigned_sessions = '';
-		if (count($assigned_sessions_id) > 0) {
-			$without_assigned_sessions = " AND s.id NOT IN(".implode(',',$assigned_sessions_id).")";
-		}
-
-		if ($_configuration['multiple_access_urls']) {
-			$sql 	= " SELECT s.id, s.name FROM $tbl_session s LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
-						WHERE  s.name LIKE '$needle%' $without_assigned_sessions AND access_url_id = ".api_get_current_access_url_id()."";
-		} else {
-			$sql = "SELECT s.id, s.name FROM $tbl_session s
-				WHERE  s.name LIKE '$needle%' $without_assigned_sessions ";
-		}
-
-		$rs	= Database::query($sql);
-
-		$return .= '<select id="origin" name="NoAssignedSessionsList[]" multiple="multiple" size="20" style="width:340px;">';
-		while($session = Database :: fetch_array($rs)) {
-			$return .= '<option value="'.$session['id'].'" title="'.htmlspecialchars($session['name'],ENT_QUOTES).'">'.$session['name'].'</option>';
-		}
-		$return .= '</select>';
-		$xajax_response->addAssign('ajax_list_sessions_multiple','innerHTML',api_utf8_encode($return));
-	}
-	return $xajax_response;
+    global $_configuration, $tbl_session_rel_access_url, $tbl_session, $user_id;
+
+    $xajax_response = new XajaxResponse();
+    $return = '';
+    if(!empty($needle) && !empty($type)) {
+        // xajax send utf8 datas... datas in db can be non-utf8 datas
+        $charset = api_get_system_encoding();
+        $needle = api_convert_encoding($needle, $charset, 'utf-8');
+        $assigned_sessions_to_hrm = SessionManager::get_sessions_followed_by_drh($user_id);
+        $assigned_sessions_id = array_keys($assigned_sessions_to_hrm);
+
+        $without_assigned_sessions = '';
+        if (count($assigned_sessions_id) > 0) {
+            $without_assigned_sessions = " AND s.id NOT IN(".implode(',',$assigned_sessions_id).")";
+        }
+
+        if ($_configuration['multiple_access_urls']) {
+            $sql 	= " SELECT s.id, s.name FROM $tbl_session s LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
+                        WHERE  s.name LIKE '$needle%' $without_assigned_sessions AND access_url_id = ".api_get_current_access_url_id()."";
+        } else {
+            $sql = "SELECT s.id, s.name FROM $tbl_session s
+                    WHERE  s.name LIKE '$needle%' $without_assigned_sessions ";
+        }
+
+        $rs	= Database::query($sql);
+
+        $return .= '<select id="origin" name="NoAssignedSessionsList[]" multiple="multiple" size="20" style="width:340px;">';
+        while($session = Database :: fetch_array($rs)) {
+            $return .= '<option value="'.$session['id'].'" title="'.htmlspecialchars($session['name'],ENT_QUOTES).'">'.$session['name'].'</option>';
+        }
+        $return .= '</select>';
+        $xajax_response->addAssign('ajax_list_sessions_multiple','innerHTML',api_utf8_encode($return));
+    }
+    return $xajax_response;
 }
 
 $xajax->processRequests();
@@ -157,7 +156,7 @@ $UserList = array();
 $msg = '';
 if (intval($_POST['formSent']) == 1) {
 	$sessions_list = $_POST['SessionsList'];
-	$affected_rows = SessionManager::suscribe_sessions_to_hr_manager($user_id,$sessions_list);
+	$affected_rows = SessionManager::suscribe_sessions_to_hr_manager($user_id, $sessions_list);
 	if ($affected_rows)	{
 		$msg = get_lang('AssignedSessionsHaveBeenUpdatedSuccessfully');
 	}
@@ -192,11 +191,11 @@ if (isset($_POST['firstLetterSession'])) {
 
 if ($_configuration['multiple_access_urls']) {
 	$sql 	= " SELECT s.id, s.name FROM $tbl_session s LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
-				WHERE  s.name LIKE '$needle%' $without_assigned_sessions AND access_url_id = ".api_get_current_access_url_id()." 
+				WHERE  s.name LIKE '$needle%' $without_assigned_sessions AND access_url_id = ".api_get_current_access_url_id()."
                 ORDER BY s.name";
 } else {
 	$sql 	= " SELECT s.id, s.name FROM $tbl_session s
-				WHERE  s.name LIKE '$needle%' $without_assigned_sessions 
+				WHERE  s.name LIKE '$needle%' $without_assigned_sessions
                 ORDER BY s.name
                 ";
 }
@@ -289,7 +288,6 @@ if(!empty($msg)) {
   </select></td>
 </tr>
 </table>
-
 </form>
 
 <?php

+ 7 - 12
main/cron/import_csv.php

@@ -139,11 +139,8 @@ class ImportCsv
 
                         $this->$method($file);
                     }
-
                 }
             }
-
-
         }
     }
 
@@ -154,7 +151,6 @@ class ImportCsv
     {
         // Create user extra field: extra_external_user_id
         UserManager::create_extra_field($this->extraFieldIdNameList['user'], 1, 'External user id', null);
-
         // Create course extra field: extra_external_course_id
         CourseManager::create_course_extra_field($this->extraFieldIdNameList['course'], 1, 'External course id');
         // Create session extra field extra_external_session_id
@@ -205,7 +201,6 @@ class ImportCsv
             $row['extra_'.$this->extraFieldIdNameList['user']] = $row['TeacherID'];
         }
 
-        //$row['lastname'] =  Status
         return $row;
     }
 
@@ -323,7 +318,7 @@ class ImportCsv
                         $row['lastname'],  // <<-- changed
                         $userInfo['username'],
                         null, //$password = null,
-                        $auth_source = null,
+                        PLATFORM_AUTH_SOURCE,
                         $userInfo['email'],
                         COURSEMANAGER,
                         $userInfo['official_code'],
@@ -378,8 +373,10 @@ class ImportCsv
             $this->logger->addInfo(count($data)." records found.");
             foreach ($data as $row) {
                 $row = $this->cleanUserRow($row);
-                //$userInfo = api_get_user_info_from_username($row['username']);
-                $user_id = UserManager::get_user_id_from_original_id($row['extra_'.$this->extraFieldIdNameList['user']], $this->extraFieldIdNameList['user']);
+                $user_id = UserManager::get_user_id_from_original_id(
+                    $row['extra_'.$this->extraFieldIdNameList['user']],
+                    $this->extraFieldIdNameList['user']
+                );
 
                 $userInfo = array();
                 $userInfoByOfficialCode = null;
@@ -481,7 +478,7 @@ class ImportCsv
                         $row['lastname'],  // <<-- changed
                         $row['username'],  // <<-- changed
                         $password, //$password = null,
-                        $auth_source = null,
+                        PLATFORM_AUTH_SOURCE,
                         $email,
                         STUDENT,
                         $userInfo['official_code'],
@@ -543,7 +540,7 @@ class ImportCsv
                     $params['wanted_code']          = $row['course_code'];
                     $params['course_category']      = $row['course_category'];
                     $params['course_language']      = $row['language'];
-                    $params['teachers'] = $row['teachers'];
+                    $params['teachers']             = $row['teachers'];
 
                     $courseInfo = CourseManager::create_course($params);
 
@@ -620,10 +617,8 @@ class ImportCsv
             foreach ($data as $row) {
                 $chamiloUserName = $row['UserName'];
                 $chamiloCourseCode = $row['CourseCode'];
-                //$systemSessionId= $row['SessionID'];
                 $chamiloSessionId = $row['SessionID'];
 
-                //$sessionId = SessionManager::get_session_id_from_original_id($systemSessionId, $this->extraFieldIdNameList['session']);
                 $sessionInfo = api_get_session_info($chamiloSessionId);
 
                 if (empty($sessionInfo)) {

+ 1 - 0
main/exercice/answer.class.php

@@ -545,6 +545,7 @@ class Answer
 
 		$this->cancel();
 	}
+
 	/**
 	 * Duplicates answers by copying them into another question
 	 *

+ 11 - 10
main/group/group.php

@@ -142,10 +142,7 @@ if (api_is_allowed_to_edit(false, true)) {
                 GroupManager :: delete_groups($my_get_id);
                 Display :: display_confirmation_message(get_lang('GroupDel'));
                 break;
-            case 'empty_one':
-                GroupManager :: unsubscribe_all_users($my_get_id);
-                Display :: display_confirmation_message(get_lang('GroupEmptied'));
-                break;
+
             case 'fill_one':
                 GroupManager :: fill_groups($my_get_id);
                 Display :: display_confirmation_message(get_lang('GroupFilledGroups'));
@@ -161,11 +158,8 @@ if (api_is_allowed_to_edit(false, true)) {
 echo '<div class="actions">';
 if (api_is_allowed_to_edit(false, true)) {
     echo '<a href="group_creation.php?'.api_get_cidreq().'">'.
-        Display::return_icon('new_group.png', get_lang('NewGroupCreate'),'',ICON_SIZE_MEDIUM).'</a>';
-    if (CourseManager::count_rows_course_table(Database::get_course_table(TABLE_GROUP), api_get_session_id(), api_get_course_int_id()) > 0) {
-        echo '<a href="group_overview.php?'.api_get_cidreq().'">'.
-            Display::return_icon('group_summary.png', get_lang('GroupOverview'), '', ICON_SIZE_MEDIUM).'</a>';
-    }
+        Display::return_icon('new_group.png', get_lang('NewGroupCreate'), '', ICON_SIZE_MEDIUM).'</a>';
+
     if (api_get_setting('allow_group_categories') == 'true') {
         echo '<a href="group_category.php?'.api_get_cidreq().'&action=add_category">'.
             Display::return_icon('new_folder.png', get_lang('AddCategory'), '', ICON_SIZE_MEDIUM).'</a>';
@@ -183,9 +177,16 @@ if (api_is_allowed_to_edit(false, true)) {
     echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export&type=xls">'.
         Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
 
+    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().'">'.
+        Display::return_icon('group_summary.png', get_lang('GroupOverview'), '', ICON_SIZE_MEDIUM).'</a>';
 
     echo '<a href="../user/user.php?'.api_get_cidreq().'">'.
         Display::return_icon('user.png', get_lang('GoTo').' '.get_lang('Users'), '', ICON_SIZE_MEDIUM).'</a>';
+
+    echo GroupManager::getSearchForm();
 }
 
 $group_cats = GroupManager::get_categories(api_get_course_id());
@@ -220,7 +221,7 @@ if (api_get_setting('allow_group_categories') == 'true') {
     }
 } else {
     $group_list = GroupManager::get_group_list();
-    GroupManager ::process_groups($group_list);
+    GroupManager::process_groups($group_list);
 }
 
 if (!isset ($_GET['origin']) || $_GET['origin'] != 'learnpath') {

+ 103 - 91
main/group/group_edit.php

@@ -33,7 +33,7 @@ $interbreadcrumb[] = array ('url' => 'group_space.php?'.api_get_cidReq(), 'name'
 $is_group_member = GroupManager :: is_tutor_of_group(api_get_user_id(), $group_id);
 
 if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
-	api_not_allowed(true);
+    api_not_allowed(true);
 }
 
 /*	FUNCTIONS */
@@ -41,68 +41,77 @@ if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
 /**
  *  List all users registered to the course
  */
-function search_members_keyword($firstname, $lastname, $username, $official_code, $keyword) {
-	if (api_strripos($firstname, $keyword) !== false || api_strripos($lastname, $keyword) !== false || api_strripos($username, $keyword) !== false || api_strripos($official_code, $keyword) !== false) {
-		return true;
-	} else {
-		return false;
-	}
+function search_members_keyword($firstname, $lastname, $username, $official_code, $keyword)
+{
+    if (api_strripos($firstname, $keyword) !== false ||
+        api_strripos($lastname, $keyword) !== false ||
+        api_strripos($username, $keyword) !== false ||
+        api_strripos($official_code, $keyword) !== false
+    ) {
+        return true;
+    } else {
+        return false;
+    }
 }
 
 /**
- * function to sort users after getting the list in the db. Necessary because there are 2 or 3 queries. Called by usort()
+ * Function to sort users after getting the list in the DB.
+ * Necessary because there are 2 or 3 queries. Called by usort()
  */
-function sort_users($user_a, $user_b) {
-	if (api_sort_by_first_name()) {
-		$cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
-		if ($cmp !== 0) {
-			return $cmp;
-		} else {
-			$cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
-			if ($cmp !== 0) {
-				return $cmp;
-			} else {
-				return api_strcmp($user_a['username'], $user_b['username']);
-			}
-		}
-	} else {
-		$cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
-		if ($cmp !== 0) {
-			return $cmp;
-		} else {
-			$cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
-			if ($cmp !== 0) {
-				return $cmp;
-			} else {
-				return api_strcmp($user_a['username'], $user_b['username']);
-			}
-		}
-	}
+function sort_users($user_a, $user_b)
+{
+    if (api_sort_by_first_name()) {
+        $cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
+        if ($cmp !== 0) {
+            return $cmp;
+        } else {
+            $cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
+            if ($cmp !== 0) {
+                return $cmp;
+            } else {
+                return api_strcmp($user_a['username'], $user_b['username']);
+            }
+        }
+    } else {
+        $cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
+        if ($cmp !== 0) {
+            return $cmp;
+        } else {
+            $cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
+            if ($cmp !== 0) {
+                return $cmp;
+            } else {
+                return api_strcmp($user_a['username'], $user_b['username']);
+            }
+        }
+    }
 }
 
 /**
  * Function to check the given max number of members per group
  */
-function check_max_number_of_members($value) {
-	$max_member_no_limit = $value['max_member_no_limit'];
-	if ($max_member_no_limit == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
-		return true;
-	}
-	$max_member = $value['max_member'];
-	return is_numeric($max_member);
+function check_max_number_of_members($value)
+{
+    $max_member_no_limit = $value['max_member_no_limit'];
+    if ($max_member_no_limit == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        return true;
+    }
+    $max_member = $value['max_member'];
+    return is_numeric($max_member);
 }
 
 /**
  * Function to check if the number of selected group members is valid
  */
-function check_group_members($value) {
-	if ($value['max_member_no_limit'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
-		return true;
-	}
-	if (isset($value['max_member']) && isset($value['group_members']) && $value['max_member'] < count($value['group_members'])) {
-		return array ('group_members' => get_lang('GroupTooMuchMembers'));
-	}
-	return true;
+function check_group_members($value)
+{
+    if ($value['max_member_no_limit'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        return true;
+    }
+    if (isset($value['max_member']) && isset($value['group_members']) && $value['max_member'] < count($value['group_members'])) {
+        return array ('group_members' => get_lang('GroupTooMuchMembers'));
+    }
+    return true;
 }
 
 /*	MAIN CODE */
@@ -129,8 +138,8 @@ $form->add_textfield('name', get_lang('GroupName'));
 $form->addElement('textarea', 'description', get_lang('Description'), array ('class' => 'span6', 'rows' => 6));
 
 $complete_user_list = GroupManager :: fill_groups_list($current_group['id']);
-
 usort($complete_user_list, 'sort_users');
+
 $possible_users = array();
 foreach ($complete_user_list as $index => $user) {
     $possible_users[$user['user_id']] = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')';
@@ -172,7 +181,7 @@ foreach ($group_member_list as $index => $user) {
 // possible : number_groups_left > 0 and is group member
 $possible_users = array();
 foreach ($complete_user_list as $index => $user) {
-     if ($user['number_groups_left'] > 0 || in_array($user['user_id'], $selected_users) )  {
+     if ($user['number_groups_left'] > 0 || in_array($user['user_id'], $selected_users)) {
         $possible_users[$user['user_id']] = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')';
      }
 }
@@ -205,9 +214,10 @@ $form->addGroup($group, 'max_member_group', null, '', false);
 $form->addRule('max_member_group', get_lang('InvalidMaxNumberOfMembers'), 'callback', 'check_max_number_of_members');
 
 // Self registration
-$group = array();
-$group[] = $form->createElement('checkbox', 'self_registration_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1);
-$group[] = $form->createElement('checkbox', 'self_unregistration_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1);
+$group = array(
+    $form->createElement('checkbox', 'self_registration_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1),
+    $form->createElement('checkbox', 'self_unregistration_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1)
+);
 $form->addGroup($group, '', Display::return_icon('user.png', get_lang('GroupSelfRegistration') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupSelfRegistration'), '', false);
 
 // Documents settings
@@ -246,33 +256,35 @@ $group[] = $form->createElement('radio', 'forum_state', null, get_lang('Private'
 $form->addGroup($group, '', Display::return_icon('forum.png', get_lang('GroupForum') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupForum'), '', false);
 
 // Wiki settings
-$group = array();
-$group[] = $form->createElement('radio', 'wiki_state', get_lang('GroupWiki'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
-$group[] = $form->createElement('radio', 'wiki_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
-$group[] = $form->createElement('radio', 'wiki_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
+$group = array(
+    $form->createElement('radio', 'wiki_state', get_lang('GroupWiki'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
+    $form->createElement('radio', 'wiki_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
+    $form->createElement('radio', 'wiki_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
+);
 $form->addGroup($group, '', Display::return_icon('wiki.png', get_lang('GroupWiki') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupWiki'), '', false);
 
 // Chat settings
-$group = array();
-$group[] = $form->createElement('radio', 'chat_state', get_lang('Chat'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
-$group[] = $form->createElement('radio', 'chat_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
-$group[] = $form->createElement('radio', 'chat_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
-$form->addGroup($group, '', Display::return_icon('chat.png', get_lang('Chat') , array(), ICON_SIZE_SMALL).' '.get_lang('Chat'), '', false);
+$group = array(
+    $form->createElement('radio', 'chat_state', get_lang('Chat'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
+    $form->createElement('radio', 'chat_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
+    $form->createElement('radio', 'chat_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
+);
+$form->addGroup($group, '', Display::return_icon('chat.png', get_lang('Chat'), array(), ICON_SIZE_SMALL).' '.get_lang('Chat'), '', false);
 
 // submit button
 $form->addElement('style_submit_button', 'submit', get_lang('SaveSettings'), 'class="save"');
 
 if ($form->validate()) {
-	$values = $form->exportValues();
-	if ($values['max_member_no_limit'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
-		$max_member = GroupManager::MEMBER_PER_GROUP_NO_LIMIT;
-	} else {
-		$max_member = $values['max_member'];
-	}
-	$self_registration_allowed   = isset($values['self_registration_allowed']) ? 1 : 0;
-	$self_unregistration_allowed = isset($values['self_unregistration_allowed']) ? 1 : 0;
-
-	GroupManager::set_group_properties(
+    $values = $form->exportValues();
+    if ($values['max_member_no_limit'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        $max_member = GroupManager::MEMBER_PER_GROUP_NO_LIMIT;
+    } else {
+        $max_member = $values['max_member'];
+    }
+    $self_registration_allowed   = isset($values['self_registration_allowed']) ? 1 : 0;
+    $self_unregistration_allowed = isset($values['self_unregistration_allowed']) ? 1 : 0;
+
+    GroupManager::set_group_properties(
         $current_group['id'],
         strip_tags($values['name']),
         strip_tags($values['description']),
@@ -288,20 +300,20 @@ if ($form->validate()) {
         $self_unregistration_allowed
     );
 
-	// Storing the tutors (we first remove all the tutors and then add only those who were selected)
-	GroupManager :: unsubscribe_all_tutors($current_group['id']);
-	if (isset ($_POST['group_tutors']) && count($_POST['group_tutors']) > 0) {
-		GroupManager :: subscribe_tutors($values['group_tutors'], $current_group['id']);
-	}
+    // Storing the tutors (we first remove all the tutors and then add only those who were selected)
+    GroupManager :: unsubscribe_all_tutors($current_group['id']);
+    if (isset ($_POST['group_tutors']) && count($_POST['group_tutors']) > 0) {
+        GroupManager :: subscribe_tutors($values['group_tutors'], $current_group['id']);
+    }
 
-	// Storing the users (we first remove all users and then add only those who were selected)
-	GroupManager :: unsubscribe_all_users($current_group['id']);
-	if (isset ($_POST['group_members']) && count($_POST['group_members']) > 0) {
-		GroupManager :: subscribe_users($values['group_members'], $current_group['id']);
-	}
+    // Storing the users (we first remove all users and then add only those who were selected)
+    GroupManager :: unsubscribe_all_users($current_group['id']);
+    if (isset ($_POST['group_members']) && count($_POST['group_members']) > 0) {
+        GroupManager :: subscribe_users($values['group_members'], $current_group['id']);
+    }
 
-	// Returning to the group area (note: this is inconsistent with the rest of chamilo)
-	$cat = GroupManager :: get_category_from_group($current_group['id']);
+    // Returning to the group area (note: this is inconsistent with the rest of chamilo)
+    $cat = GroupManager :: get_category_from_group($current_group['id']);
     if (isset($_POST['group_members']) && count($_POST['group_members']) > $max_member && $max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
         header('Location: group.php?'.api_get_cidreq(true, false).'&action=warning_message&msg='.get_lang('GroupTooMuchMembers'));
     } else {
@@ -316,22 +328,22 @@ $defaults['group_tutors'] = $selected_tutors;
 $action = isset($_GET['action']) ? $_GET['action'] : '';
 $defaults['action'] = $action;
 if ($defaults['maximum_number_of_students'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
-	$defaults['max_member_no_limit'] = GroupManager::MEMBER_PER_GROUP_NO_LIMIT;
+    $defaults['max_member_no_limit'] = GroupManager::MEMBER_PER_GROUP_NO_LIMIT;
 } else {
-	$defaults['max_member_no_limit'] = 1;
-	$defaults['max_member'] = $defaults['maximum_number_of_students'];
+    $defaults['max_member_no_limit'] = 1;
+    $defaults['max_member'] = $defaults['maximum_number_of_students'];
 }
 
 if (!empty($_GET['keyword']) && !empty($_GET['submit'])) {
-	$keyword_name = Security::remove_XSS($_GET['keyword']);
-	echo '<br/>'.get_lang('SearchResultsFor').' <span style="font-style: italic ;"> '.$keyword_name.' </span><br>';
+    $keyword_name = Security::remove_XSS($_GET['keyword']);
+    echo '<br/>'.get_lang('SearchResultsFor').' <span style="font-style: italic ;"> '.$keyword_name.' </span><br>';
 }
 
 Display :: display_header($nameTools, 'Group');
 
 //@todo fix this
 if (isset($_GET['show_message_warning'])) {
-	echo Display::display_warning_message($_GET['show_message_warning']);
+    echo Display::display_warning_message($_GET['show_message_warning']);
 }
 
 if (isset($_GET['show_message_sucess'])) {

+ 30 - 53
main/group/group_overview.php

@@ -17,7 +17,7 @@
  */
 
 // Name of the language file that needs to be included
-$language_file = 'group';
+$language_file = array('group', 'admin');
 
 require_once '../inc/global.inc.php';
 $this_section = SECTION_COURSES;
@@ -28,6 +28,7 @@ api_protect_course_script(true);
 
 $nameTools = get_lang('GroupOverview');
 $courseId = api_get_course_int_id();
+$courseInfo = api_get_course_info();
 
 /*	Libraries */
 include_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
@@ -42,6 +43,15 @@ if (isset($_GET['action'])) {
             Export::export_table_csv($data);
             exit;
             break;
+        case 'export_pdf':
+            $content = GroupManager::getOverview($courseId, $keyword);
+            $pdf = new PDF();
+            $extra = '<div style="text-align:center"><h2>'.get_lang('GroupList').'</h2></div>';
+            $extra .= '<strong>'.get_lang('Course').': </strong>'.$courseInfo['title'].' ('.$courseInfo['code'].')';
+
+            $content = $extra.$content;
+            $pdf->content_to_pdf($content, null, null, api_get_course_id());
+            break;
         case 'export':
             $groupId = isset($_GET['id']) ? intval($_GET['id']) : null;
             $groups = GroupManager::get_group_list();
@@ -70,8 +80,10 @@ if (isset($_GET['action'])) {
                     exit;
                     break;
                 case 'xls':
-                    Export::export_table_xls($data);
-                    exit;
+                    if (!empty($data)) {
+                        Export::export_table_xls($data);
+                        exit;
+                    }
                     break;
             }
             break;
@@ -80,6 +92,7 @@ if (isset($_GET['action'])) {
 
 /*	Header */
 
+
 $interbreadcrumb[] = array('url' => 'group.php', 'name' => get_lang('Groups'));
 if (!isset ($_GET['origin']) || $_GET['origin'] != 'learnpath') {
     // So we are not in learnpath tool
@@ -90,6 +103,8 @@ if (!isset ($_GET['origin']) || $_GET['origin'] != 'learnpath') {
         api_not_allowed(true);
     } else {
         Display::display_header($nameTools, 'Group');
+        // Tool introduction
+        Display::display_introduction_section(TOOL_GROUP);
     }
 } else {
 ?> <link rel="stylesheet" type="text/css" href="<?php echo api_get_path(WEB_CSS_PATH); ?>default.css" /> <?php
@@ -99,8 +114,7 @@ if (!isset ($_GET['origin']) || $_GET['origin'] != 'learnpath') {
 echo '<div class="actions">';
     echo '<a href="group_creation.php?'.api_get_cidreq().'">'.
         Display::return_icon('new_group.png', get_lang('NewGroupCreate'), '', ICON_SIZE_MEDIUM).'</a>';
-    echo '<a href="group.php?'.api_get_cidreq().'">'.
-        Display::return_icon('group.png', get_lang('Groups'),'',ICON_SIZE_MEDIUM).'</a>';
+
     if (api_get_setting('allow_group_categories') == 'true') {
         echo '<a href="group_category.php?'.api_get_cidreq().'&action=add_category">'.
             Display::return_icon('new_folder.png', get_lang('AddCategory'), '', ICON_SIZE_MEDIUM).'</a>';
@@ -115,59 +129,22 @@ echo '<div class="actions">';
         Display::return_icon('export_csv.png', get_lang('Export'), '', ICON_SIZE_MEDIUM).'</a>';
 
     echo '<a href="group_overview.php?'.api_get_cidreq().'&action=export&type=xls">'.
-        Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
+    Display::return_icon('export_excel.png', get_lang('ExportAsXLS'), '', ICON_SIZE_MEDIUM).'</a>';
 
-    $form = new FormValidator('search_groups', 'get', null, null, array('class' => 'form-search'));
-    $form->addElement('text', 'keyword');
-    $form->addElement('button', 'submit', get_lang('Search'));
-    $form->display();
-echo '</div>';
+   echo  '<a href="group_overview.php?'.api_get_cidreq().'&action=export_pdf">'.
+        Display::return_icon('pdf.png', get_lang('ExportToPDF'), '', ICON_SIZE_MEDIUM).'</a>';
 
-$categories = GroupManager::get_categories();
+    echo '<a href="group.php?'.api_get_cidreq().'">'.
+        Display::return_icon('group.png', get_lang('Groups'),'',ICON_SIZE_MEDIUM).'</a>';
 
-foreach ($categories as $category) {
-    if (api_get_setting('allow_group_categories') == 'true') {
-        echo '<h2>'.$category['title'].'</h2>';
-    }
-    if (!empty($keyword)) {
-        $groups = GroupManager::getGroupListFilterByName($keyword, $category['id'], $courseId);
-    } else {
-        $groups = GroupManager::get_group_list($category['id']);
-    }
 
-    echo '<ul>';
-    if (!empty($groups)) {
-        foreach ($groups as $group) {
-            echo '<li>';
-            echo Display::tag('h3', Security::remove_XSS($group['name']));
-
-            $users = GroupManager::getTutors($group['id']);
-            if (!empty($users)) {
-                echo '<ul>';
-                echo Display::tag('h4', get_lang('Tutors'));
-                foreach ($users as $user) {
-                    $user_info = api_get_user_info($user['user_id']);
-                    //$username = api_htmlentities(sprintf(get_lang('LoginX'), $user_info['username']), ENT_QUOTES);
-                    echo '<li title="'.$user_info['username'].'">'.$user_info['complete_name_with_username'].'</li>';
-                }
-                echo '</ul>';
-            }
+    echo '<a href="../user/user.php?'.api_get_cidreq().'">'.
+    Display::return_icon('user.png', get_lang('GoTo').' '.get_lang('Users'), '', ICON_SIZE_MEDIUM).'</a>';
 
-            $users = GroupManager::getStudents($group['id']);
-            if (!empty($users)) {
-                echo '<ul>';
-                echo Display::tag('h4', get_lang('Students'));
-                foreach ($users as $user) {
-                    $user_info = api_get_user_info($user['user_id']);
-                    echo '<li title="'.$user_info['username'].'">'.$user_info['complete_name_with_username'].'</li>';
-                }
-                echo '</ul>';
-            }
-            echo '</li>';
-        }
-    }
-    echo '</ul>';
-}
+    echo GroupManager::getSearchForm();
+echo '</div>';
+
+echo GroupManager::getOverview($courseId, $keyword);
 
 if (!isset ($_GET['origin']) || $_GET['origin'] != 'learnpath') {
     Display::display_footer();

+ 16 - 9
main/group/group_space.php

@@ -124,10 +124,13 @@ $is_course_member = CourseManager :: is_user_subscribed_in_real_or_linked_course
 $edit_url = '';
 if (api_is_allowed_to_edit(false, true) or GroupManager :: is_tutor_of_group(api_get_user_id(), api_get_group_id())) {
     $my_origin = isset($origin) ? $origin : '';
-    $edit_url =  '<a href="group_edit.php?cidReq='.  api_get_course_id().'&origin='.$my_origin.'&gidReq='.api_get_group_id().'">'.Display::return_icon('edit.png', get_lang('EditGroup'),'',ICON_SIZE_SMALL).'</a>';
+    $edit_url =  '<a href="'.api_get_path(WEB_CODE_PATH).'group/settings.php?cidReq='.api_get_course_id().'&origin='.$my_origin.'&gidReq='.api_get_group_id().'">'.
+        Display::return_icon('edit.png', get_lang('EditGroup'),'',ICON_SIZE_SMALL).'</a>';
 }
 
-echo Display::page_header(Security::remove_XSS($current_group['name']).' '.$edit_url.' '.$subscribe_group.' '.$unsubscribe_group);
+echo Display::page_header(
+    Security::remove_XSS($current_group['name']).' '.$edit_url.' '.$subscribe_group.' '.$unsubscribe_group
+);
 
 if (!empty($current_group['description'])) {
 	echo '<p>'.Security::remove_XSS($current_group['description']).'</p>';
@@ -138,9 +141,9 @@ if (!empty($current_group['description'])) {
  */
 // If the user is subscribed to the group or the user is a tutor of the group then
 if (api_is_allowed_to_edit(false, true) OR GroupManager :: is_user_in_group(api_get_user_id(), $current_group['id'])) {
-	$actions_array = array();
-	// Link to the forum of this group
-	$forums_of_groups = get_forums_of_group($current_group['id']);
+    $actions_array = array();
+    // Link to the forum of this group
+    $forums_of_groups = get_forums_of_group($current_group['id']);
 
 	if (is_array($forums_of_groups)) {
 		if ($current_group['forum_state'] != GroupManager::TOOL_NOT_AVAILABLE ) {
@@ -291,16 +294,20 @@ $tutor_info = '';
 if (count($tutors) == 0) {
 	$tutor_info = get_lang('GroupNoneMasc');
 } else {
-	isset($origin)?$my_origin = $origin:$my_origin='';
-	foreach($tutors as $index => $tutor) {
+	isset($origin) ? $my_origin = $origin:$my_origin='';
+    $tutor_info .= '<ul class="thumbnails">';
+	foreach ($tutors as $index => $tutor) {
 	    $tab_user_info = Database::get_user_info_from_id($tutor['user_id']);
 	    $username = api_htmlentities(sprintf(get_lang('LoginX'), $tab_user_info['username']), ENT_QUOTES);
 		$image_path = UserManager::get_user_picture_path_by_id($tutor['user_id'], 'web', false, true);
 		$image_repository = $image_path['dir'];
 		$existing_image = $image_path['file'];
-		$photo= '<img src="'.$image_repository.$existing_image.'" align="absbottom" alt="'.api_get_person_name($tutor['firstname'], $tutor['lastname']).'" width="32" height="32" title="'.api_get_person_name($tutor['firstname'], $tutor['lastname']).'" />';
-		$tutor_info .= '<a href="../user/userInfo.php?origin='.$my_origin.'&amp;uInfo='.$tutor['user_id'].'">'.$photo.'&nbsp;'.Display::tag('span', api_get_person_name($tutor['firstname'], $tutor['lastname']), array('title'=>$username)).'</a>';
+        $completeName = api_get_person_name($tutor['firstname'], $tutor['lastname']);
+		$photo = '<img src="'.$image_repository.$existing_image.'" alt="'.$completeName.'" width="32" height="32" title="'.$completeName.'" />';
+		$tutor_info .= '<li><a href="'.api_get_path(WEB_CODE_PATH).'user/userInfo.php?origin='.$my_origin.'&amp;uInfo='.$tutor['user_id'].'">'.
+            $photo.'&nbsp;'.$completeName.'</a></li>';
 	}
+    $tutor_info .= '</ul>';
 }
 
 echo Display::page_subheader(get_lang('GroupTutors'));

+ 222 - 0
main/group/member_settings.php

@@ -0,0 +1,222 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ *	This script displays an area where teachers can edit the group properties and member list.
+ *	Groups are also often called "teams" in the Dokeos code.
+ *
+ *	@author various contributors
+ *	@author Roan Embrechts (VUB), partial code cleanup, initial virtual course support
+ *	@package chamilo.group
+ *	@todo course admin functionality to create groups based on who is in which course (or class).
+ */
+
+/*	INIT SECTION */
+
+// Name of the language file that needs to be included
+$language_file = 'group';
+
+require_once '../inc/global.inc.php';
+$this_section = SECTION_COURSES;
+$current_course_tool  = TOOL_GROUP;
+
+// Notice for unauthorized people.
+api_protect_course_script(true);
+
+$group_id = api_get_group_id();
+$current_group = GroupManager::get_group_properties($group_id);
+
+$nameTools = get_lang('EditGroup');
+$interbreadcrumb[] = array ('url' => 'group.php', 'name' => get_lang('Groups'));
+$interbreadcrumb[] = array ('url' => 'group_space.php?'.api_get_cidReq(), 'name' => $current_group['name']);
+
+$is_group_member = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
+
+if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
+    api_not_allowed(true);
+}
+
+/*	FUNCTIONS */
+
+/**
+ *  List all users registered to the course
+ */
+function search_members_keyword($firstname, $lastname, $username, $official_code, $keyword)
+{
+    if (api_strripos($firstname, $keyword) !== false ||
+        api_strripos($lastname, $keyword) !== false ||
+        api_strripos($username, $keyword) !== false ||
+        api_strripos($official_code, $keyword) !== false
+    ) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Function to sort users after getting the list in the DB.
+ * Necessary because there are 2 or 3 queries. Called by usort()
+ */
+function sort_users($user_a, $user_b)
+{
+    if (api_sort_by_first_name()) {
+        $cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
+        if ($cmp !== 0) {
+            return $cmp;
+        } else {
+            $cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
+            if ($cmp !== 0) {
+                return $cmp;
+            } else {
+                return api_strcmp($user_a['username'], $user_b['username']);
+            }
+        }
+    } else {
+        $cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
+        if ($cmp !== 0) {
+            return $cmp;
+        } else {
+            $cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
+            if ($cmp !== 0) {
+                return $cmp;
+            } else {
+                return api_strcmp($user_a['username'], $user_b['username']);
+            }
+        }
+    }
+}
+
+/**
+ * Function to check if the number of selected group members is valid
+ */
+function check_group_members($value)
+{
+    if ($value['max_student'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        return true;
+    }
+    if (isset($value['max_student']) && isset($value['group_members']) && $value['max_student'] < count($value['group_members'])) {
+        return array('group_members' => get_lang('GroupTooMuchMembers'));
+    }
+    return true;
+}
+
+/*	MAIN CODE */
+
+$htmlHeadXtra[] = '<script>
+$(document).ready( function() {
+    $("#max_member").on("focus", function() {
+        $("#max_member_selected").attr("checked", true);
+    });
+});
+ </script>';
+
+// Build form
+$form = new FormValidator('group_edit', 'post', api_get_self().'?'.api_get_cidreq());
+$form->addElement('hidden', 'action');
+$form->addElement('hidden', 'max_student', $current_group['max_student']);
+$complete_user_list = GroupManager::fill_groups_list($current_group['id']);
+usort($complete_user_list, 'sort_users');
+$possible_users = array();
+foreach ($complete_user_list as $index => $user) {
+    $possible_users[$user['user_id']] = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')';
+}
+
+// Group members
+$group_member_list = GroupManager :: get_subscribed_users($current_group['id']);
+
+$selected_users = array ();
+foreach ($group_member_list as $index => $user) {
+    $selected_users[] = $user['user_id'];
+}
+
+// possible : number_groups_left > 0 and is group member
+$possible_users = array();
+foreach ($complete_user_list as $index => $user) {
+    if ($user['number_groups_left'] > 0 || in_array($user['user_id'], $selected_users)) {
+        $possible_users[$user['user_id']] = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')';
+    }
+}
+
+$group_members_element = $form->addElement('advmultiselect', 'group_members', get_lang('GroupMembers'), $possible_users, 'style="width: 280px;"');
+
+$group_members_element->setElementTemplate('
+{javascript}
+<table{class}>
+<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
+<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
+<tr>
+  <td valign="top">{unselected}</td>
+  <td align="center">{add}<br /><br />{remove}</td>
+  <td valign="top">{selected}</td>
+</tr>
+</table>');
+
+$group_members_element->setButtonAttributes('add', array('class' => 'btn arrowr'));
+$group_members_element->setButtonAttributes('remove', array('class' => 'btn arrowl'));
+$form->addFormRule('check_group_members');
+
+/*$url = '<a class="btn btn-danger" href="'.api_get_self().'?'.api_get_cidreq(true, false).'&action=empty&amp;id='.$group_id.'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('EmptyGroup').'">'.
+    get_lang('EmptyGroup').'</a>&nbsp;';
+$form->addElement('label', null, $url);*/
+// submit button
+$form->addElement('style_submit_button', 'submit', get_lang('SaveSettings'), 'class="save"');
+
+if ($form->validate()) {
+    $values = $form->exportValues();
+
+    // Storing the users (we first remove all users and then add only those who were selected)
+    GroupManager :: unsubscribe_all_users($current_group['id']);
+    if (isset ($_POST['group_members']) && count($_POST['group_members']) > 0) {
+        GroupManager :: subscribe_users($values['group_members'], $current_group['id']);
+    }
+
+    // Returning to the group area (note: this is inconsistent with the rest of chamilo)
+    $cat = GroupManager :: get_category_from_group($current_group['id']);
+    if (isset($_POST['group_members']) && count($_POST['group_members']) > $max_member && $max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        header('Location: group.php?'.api_get_cidreq(true, false).'&action=warning_message&msg='.get_lang('GroupTooMuchMembers'));
+    } else {
+        header('Location: group.php?'.api_get_cidreq(true, false).'&action=success_message&msg='.get_lang('GroupSettingsModified').'&category='.$cat['id']);
+    }
+    exit;
+}
+
+$action = isset($_GET['action']) ? $_GET['action'] : null;
+switch ($action) {
+    case 'empty':
+        if (api_is_allowed_to_edit(false, true)) {
+            GroupManager :: unsubscribe_all_users($group_id);
+            Display :: display_confirmation_message(get_lang('GroupEmptied'));
+        }
+        break;
+
+}
+
+
+$defaults = $current_group;
+$defaults['group_members'] = $selected_users;
+$action = isset($_GET['action']) ? $_GET['action'] : '';
+$defaults['action'] = $action;
+
+if (!empty($_GET['keyword']) && !empty($_GET['submit'])) {
+    $keyword_name = Security::remove_XSS($_GET['keyword']);
+    echo '<br/>'.get_lang('SearchResultsFor').' <span style="font-style: italic ;"> '.$keyword_name.' </span><br>';
+}
+
+Display :: display_header($nameTools, 'Group');
+
+//@todo fix this
+if (isset($_GET['show_message_warning'])) {
+    echo Display::display_warning_message($_GET['show_message_warning']);
+}
+
+if (isset($_GET['show_message_sucess'])) {
+    echo Display::display_normal_message($_GET['show_message_sucess']);
+}
+
+$form->setDefaults($defaults);
+echo GroupManager::getSettingBar('member');
+
+$form->display();
+
+Display :: display_footer();

+ 194 - 0
main/group/settings.php

@@ -0,0 +1,194 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ *	This script displays an area where teachers can edit the group properties and member list.
+ *	Groups are also often called "teams" in the Dokeos code.
+ *
+ *	@author various contributors
+ *	@author Roan Embrechts (VUB), partial code cleanup, initial virtual course support
+ *	@package chamilo.group
+ *	@todo course admin functionality to create groups based on who is in which course (or class).
+ */
+
+/*	INIT SECTION */
+
+// Name of the language file that needs to be included
+$language_file = 'group';
+
+require_once '../inc/global.inc.php';
+$this_section = SECTION_COURSES;
+$current_course_tool  = TOOL_GROUP;
+
+// Notice for unauthorized people.
+api_protect_course_script(true);
+
+$group_id = api_get_group_id();
+$current_group = GroupManager :: get_group_properties($group_id);
+
+$nameTools = get_lang('EditGroup');
+$interbreadcrumb[] = array ('url' => 'group.php', 'name' => get_lang('Groups'));
+$interbreadcrumb[] = array ('url' => 'group_space.php?'.api_get_cidReq(), 'name' => $current_group['name']);
+
+$is_group_member = GroupManager :: is_tutor_of_group(api_get_user_id(), $group_id);
+
+if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
+    api_not_allowed(true);
+}
+
+// Build form
+$form = new FormValidator('group_edit', 'post', api_get_self().'?'.api_get_cidreq());
+$form->addElement('hidden', 'action');
+
+// Group name
+$form->addElement('text', 'name', get_lang('GroupName'));
+
+// Description
+$form->addElement('textarea', 'description', get_lang('Description'), array ('class' => 'span6', 'rows' => 6));
+
+// Members per group
+$group = array(
+    $form->createElement('radio', 'max_member_no_limit', get_lang('GroupLimit'), get_lang('NoLimit'), GroupManager::MEMBER_PER_GROUP_NO_LIMIT),
+    $form->createElement('radio', 'max_member_no_limit', null, get_lang('MaximumOfParticipants'), 1, array('id' => 'max_member_selected')),
+    $form->createElement('text', 'max_member', null, array('class' => 'span1', 'id' => 'max_member')),
+    $form->createElement('static', null, null, ' '.get_lang('GroupPlacesThis'))
+);
+$form->addGroup($group, 'max_member_group', get_lang('GroupLimit'), '', false);
+$form->addRule('max_member_group', get_lang('InvalidMaxNumberOfMembers'), 'callback', 'check_max_number_of_members');
+
+$form->addElement('html', '<div class="span6">');
+
+// Self registration
+$group = array(
+    $form->createElement('checkbox', 'self_registration_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1),
+    $form->createElement('checkbox', 'self_unregistration_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1)
+);
+$form->addGroup($group, '', Display::return_icon('user.png', get_lang('GroupSelfRegistration') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupSelfRegistration'), '', false);
+
+// Documents settings
+$group = array();
+$group[] = $form->createElement('radio', 'doc_state', get_lang('GroupDocument'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
+$group[] = $form->createElement('radio', 'doc_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
+$group[] = $form->createElement('radio', 'doc_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
+$form->addGroup($group, '', Display::return_icon('folder.png', get_lang('GroupDocument') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupDocument'), '', false);
+
+// Work settings
+$group = array();
+$group[] = $form->createElement('radio', 'work_state', get_lang('GroupWork'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
+$group[] = $form->createElement('radio', 'work_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
+$group[] = $form->createElement('radio', 'work_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
+$form->addGroup($group, '', Display::return_icon('work.png', get_lang('GroupWork') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupWork'), '', false);
+
+// Calendar settings
+$group = array();
+$group[] = $form->createElement('radio', 'calendar_state', get_lang('GroupCalendar'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
+$group[] = $form->createElement('radio', 'calendar_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
+$group[] = $form->createElement('radio', 'calendar_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
+$form->addGroup($group, '', Display::return_icon('agenda.png', get_lang('GroupCalendar') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupCalendar'), '', false);
+
+$form->addElement('html', '</div>');
+$form->addElement('html', '<div class="span6">');
+
+// Announcements settings
+$group = array();
+$group[] = $form->createElement('radio', 'announcements_state', get_lang('GroupAnnouncements'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
+$group[] = $form->createElement('radio', 'announcements_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
+$group[] = $form->createElement('radio', 'announcements_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
+$form->addGroup($group, '', Display::return_icon('announce.png', get_lang('GroupAnnouncements') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupAnnouncements'), '', false);
+
+//Forum settings
+$group = array();
+$group[] = $form->createElement('radio', 'forum_state', get_lang('GroupForum'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE);
+$group[] = $form->createElement('radio', 'forum_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC);
+$group[] = $form->createElement('radio', 'forum_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE);
+$form->addGroup($group, '', Display::return_icon('forum.png', get_lang('GroupForum') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupForum'), '', false);
+
+// Wiki settings
+$group = array(
+    $form->createElement('radio', 'wiki_state', get_lang('GroupWiki'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
+    $form->createElement('radio', 'wiki_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
+    $form->createElement('radio', 'wiki_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
+);
+$form->addGroup($group, '', Display::return_icon('wiki.png', get_lang('GroupWiki') , array(), ICON_SIZE_SMALL).' '.get_lang('GroupWiki'), '', false);
+
+// Chat settings
+$group = array(
+    $form->createElement('radio', 'chat_state', get_lang('Chat'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
+    $form->createElement('radio', 'chat_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
+    $form->createElement('radio', 'chat_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE)
+);
+$form->addGroup($group, '', Display::return_icon('chat.png', get_lang('Chat'), array(), ICON_SIZE_SMALL).' '.get_lang('Chat'), '', false);
+
+$form->addElement('html', '</div>');
+
+$form->addElement('html', '<div class="span12">');
+// Submit button
+$form->addElement('style_submit_button', 'submit', get_lang('SaveSettings'), 'class="save"');
+$form->addElement('html', '</div>');
+
+if ($form->validate()) {
+    $values = $form->exportValues();
+    if ($values['max_member_no_limit'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        $max_member = GroupManager::MEMBER_PER_GROUP_NO_LIMIT;
+    } else {
+        $max_member = $values['max_member'];
+    }
+    $self_registration_allowed   = isset($values['self_registration_allowed']) ? 1 : 0;
+    $self_unregistration_allowed = isset($values['self_unregistration_allowed']) ? 1 : 0;
+
+    GroupManager::set_group_properties(
+        $current_group['id'],
+        strip_tags($values['name']),
+        strip_tags($values['description']),
+        $max_member,
+        $values['doc_state'],
+        $values['work_state'],
+        $values['calendar_state'],
+        $values['announcements_state'],
+        $values['forum_state'],
+        $values['wiki_state'],
+        $values['chat_state'],
+        $self_registration_allowed,
+        $self_unregistration_allowed
+    );
+    if (isset($_POST['group_members']) && count($_POST['group_members']) > $max_member && $max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        header('Location: group.php?'.api_get_cidreq(true, false).'&action=warning_message&msg='.get_lang('GroupTooMuchMembers'));
+    } else {
+        header('Location: group.php?'.api_get_cidreq(true, false).'&action=success_message&msg='.get_lang('GroupSettingsModified').'&category='.$cat['id']);
+    }
+    exit;
+}
+
+$defaults = $current_group;
+$action = isset($_GET['action']) ? $_GET['action'] : '';
+$defaults['action'] = $action;
+if ($defaults['maximum_number_of_students'] == GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+    $defaults['max_member_no_limit'] = GroupManager::MEMBER_PER_GROUP_NO_LIMIT;
+} else {
+    $defaults['max_member_no_limit'] = 1;
+    $defaults['max_member'] = $defaults['maximum_number_of_students'];
+}
+
+if (!empty($_GET['keyword']) && !empty($_GET['submit'])) {
+    $keyword_name = Security::remove_XSS($_GET['keyword']);
+    echo '<br/>'.get_lang('SearchResultsFor').' <span style="font-style: italic ;"> '.$keyword_name.' </span><br>';
+}
+
+Display :: display_header($nameTools, 'Group');
+
+//@todo fix this
+if (isset($_GET['show_message_warning'])) {
+    echo Display::display_warning_message($_GET['show_message_warning']);
+}
+
+if (isset($_GET['show_message_sucess'])) {
+    echo Display::display_normal_message($_GET['show_message_sucess']);
+}
+
+$form->setDefaults($defaults);
+echo GroupManager::getSettingBar('settings');
+echo '<div class="row">';
+$form->display();
+echo '</div>';
+
+Display :: display_footer();

+ 185 - 0
main/group/tutor_settings.php

@@ -0,0 +1,185 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ *	This script displays an area where teachers can edit the group properties and member list.
+ *	Groups are also often called "teams" in the Dokeos code.
+ *
+ *	@author various contributors
+ *	@author Roan Embrechts (VUB), partial code cleanup, initial virtual course support
+ *	@package chamilo.group
+ *	@todo course admin functionality to create groups based on who is in which course (or class).
+ */
+
+/*	INIT SECTION */
+
+// Name of the language file that needs to be included
+$language_file = 'group';
+
+require_once '../inc/global.inc.php';
+$this_section = SECTION_COURSES;
+$current_course_tool  = TOOL_GROUP;
+
+// Notice for unauthorized people.
+api_protect_course_script(true);
+
+$group_id = api_get_group_id();
+$current_group = GroupManager :: get_group_properties($group_id);
+
+$nameTools = get_lang('EditGroup');
+$interbreadcrumb[] = array ('url' => 'group.php', 'name' => get_lang('Groups'));
+$interbreadcrumb[] = array ('url' => 'group_space.php?'.api_get_cidReq(), 'name' => $current_group['name']);
+
+$is_group_member = GroupManager :: is_tutor_of_group(api_get_user_id(), $group_id);
+
+if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
+    api_not_allowed(true);
+}
+
+/*	FUNCTIONS */
+
+/**
+ *  List all users registered to the course
+ */
+function search_members_keyword($firstname, $lastname, $username, $official_code, $keyword)
+{
+    if (api_strripos($firstname, $keyword) !== false ||
+        api_strripos($lastname, $keyword) !== false ||
+        api_strripos($username, $keyword) !== false ||
+        api_strripos($official_code, $keyword) !== false
+    ) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/**
+ * Function to sort users after getting the list in the DB.
+ * Necessary because there are 2 or 3 queries. Called by usort()
+ */
+function sort_users($user_a, $user_b)
+{
+    if (api_sort_by_first_name()) {
+        $cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
+        if ($cmp !== 0) {
+            return $cmp;
+        } else {
+            $cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
+            if ($cmp !== 0) {
+                return $cmp;
+            } else {
+                return api_strcmp($user_a['username'], $user_b['username']);
+            }
+        }
+    } else {
+        $cmp = api_strcmp($user_a['lastname'], $user_b['lastname']);
+        if ($cmp !== 0) {
+            return $cmp;
+        } else {
+            $cmp = api_strcmp($user_a['firstname'], $user_b['firstname']);
+            if ($cmp !== 0) {
+                return $cmp;
+            } else {
+                return api_strcmp($user_a['username'], $user_b['username']);
+            }
+        }
+    }
+}
+
+
+/*	MAIN CODE */
+
+$htmlHeadXtra[] = '<script>
+$(document).ready( function() {
+    $("#max_member").on("focus", function() {
+        $("#max_member_selected").attr("checked", true);
+    });
+});
+ </script>';
+
+// Build form
+$form = new FormValidator('group_edit', 'post', api_get_self().'?'.api_get_cidreq());
+$form->addElement('hidden', 'action');
+
+// Group tutors
+$group_tutor_list = GroupManager :: get_subscribed_tutors($current_group['id']);
+$selected_users = array();
+$selected_tutors = array();
+foreach ($group_tutor_list as $index => $user) {
+    $selected_tutors[] = $user['user_id'];
+}
+
+$complete_user_list = GroupManager :: fill_groups_list($current_group['id']);
+usort($complete_user_list, 'sort_users');
+
+$possible_users = array();
+foreach ($complete_user_list as $index => $user) {
+    $possible_users[$user['user_id']] = api_get_person_name($user['firstname'], $user['lastname']).' ('.$user['username'].')';
+}
+
+$group_tutors_element = $form->addElement('advmultiselect', 'group_tutors', get_lang('GroupTutors'), $possible_users, 'style="width: 280px;"');
+$group_tutors_element->setElementTemplate('
+{javascript}
+<table{class}>
+<!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
+<!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
+<tr>
+  <td valign="top">{unselected}</td>
+  <td align="center">{add}<br /><br />{remove}</td>
+  <td valign="top">{selected}</td>
+</tr>
+</table>
+');
+
+$group_tutors_element->setButtonAttributes('add', array('class' => 'btn arrowr'));
+$group_tutors_element->setButtonAttributes('remove', array('class' => 'btn arrowl'));
+
+// submit button
+$form->addElement('style_submit_button', 'submit', get_lang('SaveSettings'), 'class="save"');
+
+if ($form->validate()) {
+    $values = $form->exportValues();
+
+    // Storing the tutors (we first remove all the tutors and then add only those who were selected)
+    GroupManager :: unsubscribe_all_tutors($current_group['id']);
+    if (isset ($_POST['group_tutors']) && count($_POST['group_tutors']) > 0) {
+        GroupManager :: subscribe_tutors($values['group_tutors'], $current_group['id']);
+    }
+
+    // Returning to the group area (note: this is inconsistent with the rest of chamilo)
+    $cat = GroupManager::get_category_from_group($current_group['id']);
+    if (isset($_POST['group_members']) && count($_POST['group_members']) > $max_member && $max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT) {
+        header('Location: group.php?'.api_get_cidreq(true, false).'&action=warning_message&msg='.get_lang('GroupTooMuchMembers'));
+    } else {
+        header('Location: group.php?'.api_get_cidreq(true, false).'&action=success_message&msg='.get_lang('GroupSettingsModified').'&category='.$cat['id']);
+    }
+    exit;
+}
+
+$defaults = $current_group;
+$defaults['group_tutors'] = $selected_tutors;
+$action = isset($_GET['action']) ? $_GET['action'] : '';
+$defaults['action'] = $action;
+
+if (!empty($_GET['keyword']) && !empty($_GET['submit'])) {
+    $keyword_name = Security::remove_XSS($_GET['keyword']);
+    echo '<br/>'.get_lang('SearchResultsFor').' <span style="font-style: italic ;"> '.$keyword_name.' </span><br>';
+}
+
+Display :: display_header($nameTools, 'Group');
+
+//@todo fix this
+if (isset($_GET['show_message_warning'])) {
+    echo Display::display_warning_message($_GET['show_message_warning']);
+}
+
+if (isset($_GET['show_message_sucess'])) {
+    echo Display::display_normal_message($_GET['show_message_sucess']);
+}
+
+$form->setDefaults($defaults);
+echo GroupManager::getSettingBar('tutor');
+$form->display();
+
+Display :: display_footer();

+ 65 - 11
main/inc/lib/course_category.lib.php

@@ -10,6 +10,22 @@ function isMultipleUrlSupport()
     return false;
 }
 
+/**
+ * @param int $categoryId
+ * @return array
+ */
+function getCategoryById($categoryId)
+{
+    $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
+    $categoryId = Database::escape_string($categoryId);
+    $sql = "SELECT * FROM $tbl_category WHERE id = '$categoryId'";
+    $result = Database::query($sql);
+    if (Database::num_rows($result)) {
+        return Database::fetch_array($result, 'ASSOC');
+    }
+    return array();
+}
+
 /**
  * @param string $category
  * @return array
@@ -94,7 +110,7 @@ function addNode($code, $name, $canHaveCourses, $parent_id)
     $row = Database::fetch_array($result);
     $tree_pos = $row['maxTreePos'] + 1;
 
-    $sql = "INSERT INTO $tbl_category(name,code,parent_id,tree_pos,children_count,auth_course_child)
+    $sql = "INSERT INTO $tbl_category(name, code, parent_id, tree_pos, children_count, auth_course_child)
             VALUES('$name','$code'," .(empty($parent_id) ? "NULL" : "'$parent_id'") . ",'$tree_pos','0','$canHaveCourses')";
     Database::query($sql);
     $categoryId = Database::insert_id();
@@ -134,7 +150,7 @@ function deleteNode($node)
 
     $node = Database::escape_string($node);
 
-    $result = Database::query("SELECT parent_id,tree_pos FROM $tbl_category WHERE code='$node'");
+    $result = Database::query("SELECT parent_id, tree_pos FROM $tbl_category WHERE code='$node'");
 
     if ($row = Database::fetch_array($result)) {
         if (!empty($row['parent_id'])) {
@@ -171,19 +187,18 @@ function editNode($code, $name, $canHaveCourses, $old_code)
     $old_code = Database::escape_string($old_code);
     $canHaveCourses = Database::escape_string($canHaveCourses);
 
-    if ($code != $old_code) {
-        $sql = "SELECT 1 FROM $tbl_category WHERE code='$code'";
-        $result = Database::query($sql);
-        if (Database::num_rows($result)) {
-            return false;
-        }
-    }
-
     $code = generate_course_code($code);
+    // Updating category
     $sql = "UPDATE $tbl_category SET name='$name', code='$code', auth_course_child = '$canHaveCourses'
-            WHERE code='$old_code'";
+            WHERE code = '$old_code'";
     Database::query($sql);
 
+    // Updating children
+    $sql = "UPDATE $tbl_category SET parent_id = '$code'
+            WHERE parent_id = '$old_code'";
+    Database::query($sql);
+
+    // Updating course category
     $sql = "UPDATE $tbl_course SET category_code = '$code' WHERE category_code = '$old_code' ";
     Database::query($sql);
     return true;
@@ -238,6 +253,24 @@ function compterFils($pere, $cpt)
     return ($cpt + 1);
 }
 
+/**
+ * @param string $categoryCode
+ * @return array
+ */
+function getChildren($categoryCode)
+{
+    $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
+    $categoryCode = Database::escape_string($categoryCode);
+    $result = Database::query("SELECT code, id FROM $tbl_category WHERE parent_id = '$categoryCode'");
+    $children = array();
+    while ($row = Database::fetch_array($result, 'ASSOC')) {
+        $children[] = $row;
+        $subChildren = getChildren($row['code']);
+        $children = array_merge($children, $subChildren);
+    }
+    return $children;
+}
+
 /**
  * @param string $categorySource
  * @return string
@@ -583,6 +616,27 @@ function setCategoriesInForm($form, $defaultCode = null, $parentCode = null , $p
     }
 }
 
+/**
+ * @param array $list
+ * @return array
+ */
+function getCourseCategoryNotInList($list)
+{
+    $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
+    if (empty($list)) {
+        return array();
+    }
+
+    $list = array_map('intval', $list);
+    $listToString = implode("','", $list);
+
+    $sql = "SELECT * FROM $table WHERE id NOT IN ('$listToString') AND (parent_id IS NULL) ";
+    $result = Database::query($sql);
+    return Database::store_result($result, 'ASSOC');
+}
+
+
+
 /**
  CREATE TABLE IF NOT EXISTS access_url_rel_course_category (access_url_id int unsigned NOT NULL, course_category_id int unsigned NOT NULL, PRIMARY KEY (access_url_id, course_category_id));
  */

+ 18 - 15
main/inc/lib/exercise_show_functions.lib.php

@@ -15,7 +15,8 @@
  * Class
  * @package chamilo.library
  */
-class ExerciseShowFunctions {
+class ExerciseShowFunctions
+{
 
 	/**
 	 * Shows the answer to a fill-in-the-blanks question, as HTML
@@ -57,7 +58,8 @@ class ExerciseShowFunctions {
 	 * @param int       Question ID
 	 * @return void
 	 */
-	static function display_free_answer($feedback_type, $answer, $exe_id, $questionId, $questionScore = null) {
+	static function display_free_answer($feedback_type, $answer, $exe_id, $questionId, $questionScore = null)
+    {
         $comments = get_comments($exe_id, $questionId);
 
         if (!empty($answer)) {
@@ -76,7 +78,8 @@ class ExerciseShowFunctions {
         }
 	}
 
-	static function display_oral_expression_answer($feedback_type, $answer, $id, $questionId, $nano = null) {
+	static function display_oral_expression_answer($feedback_type, $answer, $id, $questionId, $nano = null)
+    {
 		if (isset($nano)) {
 			echo $nano->show_audio_file();
 		}
@@ -162,9 +165,9 @@ class ExerciseShowFunctions {
 			<td valign="top" align="left" >
 				<?php
                 if ($studentChoice) {
-                    echo '<span style="font-weight: bold; color: #008000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                    echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
                 } else {
-                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
                 }
 
 				?>
@@ -221,18 +224,18 @@ class ExerciseShowFunctions {
             if ($studentChoice) {
 				if ($answerCorrect) {
                     $color = 'green';
-					//echo '<span style="font-weight: bold; color: #008000;">'.nl2br(make_clickable($answerComment)).'</span>';
+					//echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
 				} else {
                     $color = 'black';
-                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
 				}
-                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br(make_clickable($answerComment)).'</span>';
+                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
 
 			} else {
 				if ($answerCorrect) {
-					//echo '<span style="font-weight: bold; color: #000;">'.nl2br(make_clickable($answerComment)).'</span>';
+					//echo '<span style="font-weight: bold; color: #000;">'.nl2br($answerComment).'</span>';
 				} else {
-                    //echo '<span style="font-weight: normal; color: #000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                    //echo '<span style="font-weight: normal; color: #000;">'.nl2br($answerComment).'</span>';
 				}
 			}
 			?>
@@ -311,7 +314,7 @@ class ExerciseShowFunctions {
                 if ($studentChoice == $answerCorrect) {
                     $color = "green";
                 }
-                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br(make_clickable($answerComment)).'</span>';
+                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
             }
             ?>
         </td>
@@ -389,15 +392,15 @@ class ExerciseShowFunctions {
                 if ($studentChoice == $answerCorrect) {
                     $color = "green";
                 }
-                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br(make_clickable($answerComment)).'</span>';
+                echo '<span style="font-weight: bold; color: '.$color.';">'.nl2br($answerComment).'</span>';
             }
             if ($studentChoice == 2 || $studentChoice == '') {
-            	//echo '<span style="font-weight: bold; color: #000;">'.nl2br(make_clickable($answerComment)).'</span>';
+            	//echo '<span style="font-weight: bold; color: #000;">'.nl2br($answerComment).'</span>';
             } else {
 				if ($studentChoice == $answerCorrect) {
-	            	//echo '<span style="font-weight: bold; color: #008000;">'.nl2br(make_clickable($answerComment)).'</span>';
+	            	//echo '<span style="font-weight: bold; color: #008000;">'.nl2br($answerComment).'</span>';
 				} else {
-                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br(make_clickable($answerComment)).'</span>';
+                    //echo '<span style="font-weight: bold; color: #FF0000;">'.nl2br($answerComment).'</span>';
 				}
             }
             ?>

+ 155 - 24
main/inc/lib/groupmanager.lib.php

@@ -454,6 +454,7 @@ class GroupManager
         $result['tutor_id']                     = isset($db_object->tutor_id)?$db_object->tutor_id:null;
         $result['description']                    = $db_object->description;
         $result['maximum_number_of_students']     = $db_object->max_student;
+        $result['max_student']     = $db_object->max_student;
         $result['doc_state']                     = $db_object->doc_state;
         $result['work_state']                     = $db_object->work_state;
         $result['calendar_state']                 = $db_object->calendar_state;
@@ -1148,7 +1149,6 @@ class GroupManager
             foreach ($group_available_place as $group_id => $place) {
                 foreach ($userToken as $user_id => $places) {
                     if (self :: can_user_subscribe($user_id, $group_id)) {
-
                         self :: subscribe_users($user_id, $group_id);
                         $group_available_place[$group_id]--;
                         //$userToken[$user_id]--;
@@ -1848,7 +1848,8 @@ class GroupManager
     /**
      * Get all groups where a specific user is subscribed
      */
-    public static function get_user_group_name ($user_id) {
+    public static function get_user_group_name($user_id)
+    {
         $table_group_user   = Database::get_course_table(TABLE_GROUP_USER);
         $table_group        = Database::get_course_table(TABLE_GROUP);
         $user_id            = intval($user_id);
@@ -1868,7 +1869,7 @@ class GroupManager
 
     /**
      *
-     * see : fill_groups
+     * See : fill_groups
      *       Fill the groups with students.
      *
      * note : optimize fill_groups_list <--> fill_groups
@@ -1881,43 +1882,52 @@ class GroupManager
         $group_ids = array_map('intval', $group_ids);
 
         if (api_is_course_coach()) {
-            for($i=0 ; $i<count($group_ids) ; $i++) {
-                if(!api_is_element_in_the_session(TOOL_GROUP,$group_ids[$i])) {
-                    array_splice($group_ids,$i,1);
+            for ($i=0 ; $i<count($group_ids) ; $i++) {
+                if (!api_is_element_in_the_session(TOOL_GROUP,$group_ids[$i])) {
+                    array_splice($group_ids, $i, 1);
                     $i--;
                 }
             }
-            if (count($group_ids)==0){
-                return false;}
+            if (count($group_ids)==0) {
+                return false;
+            }
         }
 
         global $_course;
+
+        $session_id = api_get_session_id();
+        $course_id = api_get_course_int_id();
+
         $category = self::get_category_from_group($group_ids[0]);
         $groups_per_user = $category['groups_per_user'];
         $group_table = Database :: get_course_table(TABLE_GROUP);
         $group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
-        $session_id = api_get_session_id();
+
+
         $complete_user_list = CourseManager :: get_real_and_linked_user_list($_course['sysCode'], true, $session_id);
         $number_groups_per_user = ($groups_per_user == self::GROUP_PER_MEMBER_NO_LIMIT ? self::INFINITE : $groups_per_user);
-        $course_id = api_get_course_int_id();
+
         /*
          * Retrieve all the groups where enrollment is still allowed
          * (reverse) ordered by the number of place available
          */
-        $sql = "SELECT g.id gid, g.max_student - count(ug.user_id) nbPlaces, g.max_student
+        $sql = "SELECT g.id gid, count(ug.user_id) count_users, g.max_student
                 FROM ".$group_table." g
                 LEFT JOIN  ".$group_user_table." ug
                 ON    g.id = ug.group_id
                 WHERE   g.c_id = $course_id AND
                         ug.c_id = $course_id AND
                         g.id IN (".implode(',', $group_ids).")
-                GROUP BY (g.id)
-                HAVING (nbPlaces > 0 OR g.max_student = ".self::MEMBER_PER_GROUP_NO_LIMIT.")
-                ORDER BY nbPlaces DESC";
+                GROUP BY (g.id)";
 
         $sql_result = Database::query($sql);
-        $group_available_place = array ();
+        $group_available_place = array();
         while ($group = Database::fetch_array($sql_result, 'ASSOC')) {
+            if (!empty($group['max_student'])) {
+                $places = intval($group['max_student'] - $group['count_users']);
+            } else {
+                $places = self::MEMBER_PER_GROUP_NO_LIMIT;
+            }
             $group_available_place[$group['gid']] = $group['nbPlaces'];
         }
 
@@ -1933,11 +1943,11 @@ class GroupManager
             $complete_user_list[$i]['number_groups_left'] = $number_groups_per_user - $number_of_groups;
         }
         //first sort by user_id to filter out duplicates
-        $complete_user_list = TableSort :: sort_table($complete_user_list, 'user_id');
-        $complete_user_list = self :: filter_duplicates($complete_user_list, 'user_id');
+        $complete_user_list = TableSort::sort_table($complete_user_list, 'user_id');
+        $complete_user_list = self::filter_duplicates($complete_user_list, 'user_id');
         //$complete_user_list = self :: filter_only_students($complete_user_list);
         //now sort by # of group left
-        $complete_user_list = TableSort :: sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
+        $complete_user_list = TableSort::sort_table($complete_user_list, 'number_groups_left', SORT_DESC);
         return $complete_user_list;
     }
 
@@ -2042,19 +2052,27 @@ class GroupManager
                     $row[] = '-';
                 }
             }
-
+            $url = api_get_path(WEB_CODE_PATH).'group/';
             // Edit-links
             if (api_is_allowed_to_edit(false, true)  && !(api_is_course_coach() && intval($this_group['session_id']) != $session_id)) {
-                $edit_actions = '<a href="group_edit.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('Edit').'">'.
+                $edit_actions = '<a href="'.$url.'settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('Edit').'">'.
                     Display::return_icon('edit.png', get_lang('EditGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';
-                $edit_actions .= '<a href="group_overview.php?action=export&type=xls&'.api_get_cidreq(true, false).'&id='.$this_group['id'].'"  title="'.get_lang('ExportUsers').'">'.
-                    Display::return_icon('export_excel.png', get_lang('ExportUsers'),'', ICON_SIZE_SMALL).'</a>&nbsp;';
-                $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&amp;action=empty_one&amp;id='.$this_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('EmptyGroup').'">'.
-                    Display::return_icon('clean.png',get_lang('EmptyGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';
+
+                $edit_actions .= '<a href="'.$url.'member_settings.php?'.api_get_cidreq(true, false).'&gidReq='.$this_group['id'].'"  title="'.get_lang('GroupMembers').'">'.
+                    Display::return_icon('user.png', get_lang('GroupMembers'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
+
+                $edit_actions .= '<a href="'.$url.'group_overview.php?action=export&type=xls&'.api_get_cidreq(true, false).'&id='.$this_group['id'].'"  title="'.get_lang('ExportUsers').'">'.
+                    Display::return_icon('export_excel.png', get_lang('Export'), '', ICON_SIZE_SMALL).'</a>&nbsp;';
+
+                /*$edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&amp;action=empty_one&amp;id='.$this_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('EmptyGroup').'">'.
+                    Display::return_icon('clean.png',get_lang('EmptyGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';*/
+
                 $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&amp;action=fill_one&amp;id='.$this_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;" title="'.get_lang('FillGroup').'">'.
                     Display::return_icon('fill.png',get_lang('FillGroup'),'',ICON_SIZE_SMALL).'</a>&nbsp;';
+
                 $edit_actions .= '<a href="'.api_get_self().'?'.api_get_cidreq(true, false).'&category='.$category_id.'&amp;action=delete_one&amp;id='.$this_group['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>&nbsp;';
+
                 $row[] = $edit_actions;
             }
             if (!empty($this_group['nbMember'])) {
@@ -2315,4 +2333,117 @@ class GroupManager
         }
         return $data;
     }
+
+    static function getSettingBar($default)
+    {
+        $activeSettings = null;
+        $activeTutor = null;
+        $activeMember = null;
+
+        switch($default) {
+            case 'settings':
+                $activeSettings = 'active';
+                break;
+            case'tutor':
+                $activeTutor = 'active';
+                break;
+            case 'member':
+                $activeMember = 'active';
+                break;
+        }
+
+        $url = api_get_path(WEB_CODE_PATH).'group/%s?'.api_get_cidreq();
+
+        echo '
+            <ul class="nav nav-tabs">
+                <li class="'.$activeSettings.'">
+                    <a href="'.sprintf($url, 'settings.php').'">
+                    '.Display::return_icon('settings.png').' '.get_lang('Settings').'
+                    </a>
+                </li>
+                <li class="'.$activeMember.'">
+                    <a href="'.sprintf($url, 'member_settings.php').'">
+                    '.Display::return_icon('user.png').' '.get_lang('GroupMembers').'
+                    </a>
+                </li>
+                <li class="'.$activeTutor.'">
+                    <a href="'.sprintf($url, 'tutor_settings.php').'">
+                    '.Display::return_icon('teacher.png').' '.get_lang('GroupTutors').'
+                    </a>
+                </li>
+        </ul>';
+    }
+
+    /**
+     * @param int $courseId
+     * @param string $keyword
+     * @return string
+     */
+    public static function getOverview($courseId, $keyword = null)
+    {
+        $content = null;
+        $categories = GroupManager::get_categories();
+        if (!empty($categories)) {
+
+            foreach ($categories as $category) {
+                if (api_get_setting('allow_group_categories') == 'true') {
+                    $content .= '<h2>'.$category['title'].'</h2>';
+                }
+                if (!empty($keyword)) {
+                    $groups = GroupManager::getGroupListFilterByName($keyword, $category['id'], $courseId);
+                } else {
+                    $groups = GroupManager::get_group_list($category['id']);
+                }
+
+                $content .= '<ul>';
+                if (!empty($groups)) {
+                    foreach ($groups as $group) {
+                        $content .= '<li>';
+                        $content .= Display::tag('h3', Security::remove_XSS($group['name']));
+
+                        $users = GroupManager::getTutors($group['id']);
+                        if (!empty($users)) {
+                            $content .= '<ul>';
+                            $content .= "<li>".Display::tag('h4', get_lang('Tutors'))."</li><ul>";
+                            foreach ($users as $user) {
+                                $user_info = api_get_user_info($user['user_id']);
+                                $content .= '<li title="'.$user_info['username'].'">'.$user_info['complete_name_with_username'].'</li>';
+                            }
+                            $content .= '</ul>';
+                            $content .= '</ul>';
+                        }
+
+                        $users = GroupManager::getStudents($group['id']);
+                        if (!empty($users)) {
+                            $content .= '<ul>';
+                            $content .= "<li>".Display::tag('h4', get_lang('Students'))."</li><ul>";
+                            foreach ($users as $user) {
+                                $user_info = api_get_user_info($user['user_id']);
+                                $content .= '<li title="'.$user_info['username'].'">'.$user_info['complete_name_with_username'].'</li>';
+                            }
+                            $content .= '</ul>';
+                            $content .= '</ul>';
+                        }
+                        $content .= '</li>';
+                    }
+                }
+                $content .= '</ul>';
+            }
+        }
+
+        return $content;
+    }
+
+    /**
+     * Returns the search form
+     * @return string
+     */
+    public static function getSearchForm()
+    {
+        $url = api_get_path(WEB_CODE_PATH).'group/group_overview.php?'.api_get_cidreq();
+        $form = new FormValidator('search_groups', 'get', $url, null, array('class' => 'form-search'));
+        $form->addElement('text', 'keyword');
+        $form->addElement('button', 'submit', get_lang('Search'));
+        return $form->toHtml();
+    }
 }

+ 2 - 0
main/inc/lib/internationalization.lib.php

@@ -1111,10 +1111,12 @@ function api_is_western_name_order($format = null, $language = null) {
     }
 
     $language_is_supported = api_is_language_supported($language);
+
     if (!$language_is_supported || empty($language)) {
         $language = api_get_interface_language(false, true);
     }
     if (!isset($order[$format][$language])) {
+
         $test_name = api_get_person_name('%f', '%l', '%t', $format, $language);
         $order[$format][$language] = stripos($test_name, '%f') <= stripos($test_name, '%l');
     }

+ 92 - 49
main/inc/lib/pdf.lib.php

@@ -8,7 +8,9 @@
  */
 define('_MPDF_PATH', api_get_path(LIBRARY_PATH).'mpdf/');
 require_once _MPDF_PATH.'mpdf.php';
-
+/**
+ * Class PDF
+ */
 class PDF
 {
     public $pdf;
@@ -121,13 +123,13 @@ class PDF
 
         if (is_array($html_file_array)) {
             if (count($html_file_array) == 0) {
-            return false;
+                return false;
             }
         } else {
             if (!file_exists($html_file_array)) {
                 return false;
             }
-            //Converting the string into an array
+            // Converting the string into an array
             $html_file_array = array($html_file_array);
         }
 
@@ -137,13 +139,13 @@ class PDF
             $course_data = api_get_course_info();
         }
 
-        //clean styles and javascript document
+        // Clean styles and javascript document
         $clean_search = array (
             '@<script[^>]*?>.*?</script>@si',
             '@<style[^>]*?>.*?</style>@si'
             );
 
-        //Formatting the pdf
+        // Formatting the pdf
         self::format_pdf($course_data, $complete_style);
 
         $counter = 1;
@@ -168,7 +170,7 @@ class PDF
             }
 
             if (empty($file) && !empty($html_title)) {
-            	//this is a chapter, print title & skip the rest
+                //this is a chapter, print title & skip the rest
                 if ($print_title) {
                     $this->pdf->WriteHTML('<html><body><h3>'.$html_title.'</h3></body></html>'.$page_break, 2);
                 }
@@ -177,7 +179,7 @@ class PDF
 
             if (!file_exists($file)) {
                 //the file doesn't exist, skip
-            	continue;
+                continue;
             }
 
             //it's not a chapter but the file exists, print its title
@@ -243,9 +245,10 @@ class PDF
                 }
 
                 api_set_encoding_html($document_html, 'UTF-8'); // The library mPDF expects UTF-8 encoded input data.
-                $title = api_get_title_html($document_html, 'UTF-8', 'UTF-8');  // TODO: Maybe it is better idea the title to be passed through
-                                                                                // $_GET[] too, as it is done with file name.
-                                                                         // At the moment the title is retrieved from the html document itself.
+                // TODO: Maybe it is better idea the title to be passed through
+                $title = api_get_title_html($document_html, 'UTF-8', 'UTF-8');
+                // $_GET[] too, as it is done with file name.
+                // At the moment the title is retrieved from the html document itself.
                 //echo $document_html;exit;
                 if (empty($title)) {
                     $title = $filename; // Here file name is expected to contain ASCII symbols only.
@@ -264,9 +267,9 @@ class PDF
             $output_file = 'pdf_'.date('Y-m-d-his').'.pdf';
         } else {
             $pdf_name = replace_dangerous_char($pdf_name);
-        	$output_file = $pdf_name.'.pdf';
+            $output_file = $pdf_name.'.pdf';
         }
-        $result = $this->pdf->Output($output_file, 'D');       /// F to save the pdf in a file
+        $this->pdf->Output($output_file, 'D');       /// F to save the pdf in a file
         exit;
     }
 
@@ -280,7 +283,6 @@ class PDF
      */
     public function content_to_pdf($document_html, $css = '', $pdf_name = '', $course_code = null)
     {
-
         if (empty($document_html)) {
             return false;
         }
@@ -291,7 +293,7 @@ class PDF
             '@<style[^>]*?>.*?</style>@siU'
             );
 
-        //Formatting the pdf
+        // Formatting the pdf
        	$course_data = api_get_course_info($course_code);
 
         self::format_pdf($course_data);
@@ -347,8 +349,8 @@ class PDF
 
         api_set_encoding_html($document_html, 'UTF-8'); // The library mPDF expects UTF-8 encoded input data.
         $title = api_get_title_html($document_html, 'UTF-8', 'UTF-8');  // TODO: Maybe it is better idea the title to be passed through
-                                                                        // $_GET[] too, as it is done with file name.
-                                                                        // At the moment the title is retrieved from the html document itself.
+        // $_GET[] too, as it is done with file name.
+        // At the moment the title is retrieved from the html document itself.
 
         if (!empty($css)) {
             $this->pdf->WriteHTML($css, 1);
@@ -361,7 +363,7 @@ class PDF
             $pdf_name = replace_dangerous_char($pdf_name);
             $output_file = $pdf_name.'.pdf';
         }
-        $result = $this->pdf->Output($output_file, 'D'); // F to save the pdf in a file
+        $this->pdf->Output($output_file, 'D'); // F to save the pdf in a file
         exit;
     }
 
@@ -396,15 +398,18 @@ class PDF
     {
         if (!empty($course_code) && api_get_setting('pdf_export_watermark_by_course') == 'true') {
             $course_info = api_get_course_info($course_code);
-            $store_path  = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/'.api_get_current_access_url_id().'_pdf_watermark.png';   // course path
+            // course path
+            $store_path  = api_get_path(SYS_COURSE_PATH).$course_info['path'].'/'.api_get_current_access_url_id().'_pdf_watermark.png';
+
         } else {
-            $store_path = api_get_path(SYS_CODE_PATH).'default_course_document/images/'.api_get_current_access_url_id().'_pdf_watermark.png';   // course path
+            // course path
+            $store_path = api_get_path(SYS_CODE_PATH).'default_course_document/images/'.api_get_current_access_url_id().'_pdf_watermark.png';
         }
         if (file_exists($store_path)) {
-            @unlink($store_path);
+            unlink($store_path);
             return true;
         }
-    	return false;
+        return false;
     }
 
     /**
@@ -454,7 +459,8 @@ class PDF
     /**
      *
      */
-    public function set_footer() {
+    public function set_footer()
+    {
         $this->pdf->defaultfooterfontsize = 12;   // in pts
         $this->pdf->defaultfooterfontstyle = B;   // blank, B, I, or BI
         $this->pdf->defaultfooterline = 1;        // 1 to include line below header/above footer
@@ -489,11 +495,10 @@ class PDF
     }
 
     /**
-     * @param $course_data
+     * @param array $course_data
      */
     public function set_header($course_data)
     {
-
         $this->pdf->defaultheaderfontsize   = 10;   // in pts
         $this->pdf->defaultheaderfontstyle  = BI;   // blank, B, I, or BI
         $this->pdf->defaultheaderline       = 1;    // 1 to include line below header/above footer
@@ -503,7 +508,6 @@ class PDF
             $teachers = '';
             if (!empty($teacher_list)) {
                 foreach ($teacher_list as $teacher) {
-                    //$teachers[]= api_get_person_name($teacher['firstname'], $teacher['lastname']);
                     $teachers[]= $teacher['firstname'].' '.$teacher['lastname'];
                 }
                 if (count($teachers) > 1) {
@@ -512,7 +516,7 @@ class PDF
                     $teachers = get_lang('Teacher').': '.implode('', $teachers);
                 }
 
-                //do not show the teacher list see BT#4080 only the current teacher name
+                // Do not show the teacher list see BT#4080 only the current teacher name
                 $user_info = api_get_user_info();
                 $teachers = $user_info['complete_name'];
             }
@@ -521,35 +525,73 @@ class PDF
             $center_content  = '';
             $right_content   = $teachers;
 
-            $header = array (
-              'odd' => array (
-                'L' => array (
-                  'content' => $left_content,  'font-size' => 10,'font-style' => 'B','font-family' => 'serif','color'=>'#000000'),
-                'C' => array (
-                  'content' => $center_content,'font-size' => 10,'font-style' => 'B','font-family' => 'serif','color'=>'#000000'),
-                'R' => array (
-                  'content' => $right_content, 'font-size' => 10,'font-style' => 'B','font-family' => 'serif','color'=>'#000000'),
-                'line' => 1,
-              ),
-             'even' => array (
-                'L' => array (
-                  'content' => $left_content,  'font-size' => 10,'font-style' => 'B','font-family' => 'serif','color'=>'#000000'),
-                'C' => array (
-                  'content' => $center_content,'font-size' => 10,'font-style' => 'B','font-family' => 'serif','color'=>'#000000'),
-                'R' => array (
-                  'content' => $right_content, 'font-size' => 10,'font-style' => 'B','font-family' => 'serif','color'=>'#000000'),
-                'line' => 1,
-              ),
+            $header = array(
+                'odd' => array(
+                    'L' => array(
+                        'content' => $left_content,
+                        'font-size' => 10,
+                        'font-style' => 'B',
+                        'font-family' => 'serif',
+                        'color'=>'#000000'
+                    ),
+                    'C' => array(
+                        'content' => $center_content,
+                        'font-size' => 10,
+                        'font-style' => 'B',
+                        'font-family' => 'serif',
+                        'color'=>'#000000'
+                    ),
+                    'R' => array(
+                        'content' => $right_content,
+                        'font-size' => 10,
+                        'font-style' => 'B',
+                        'font-family' => 'serif',
+                        'color'=>'#000000'
+                    ),
+                    'line' => 1,
+                ),
+                'even' => array(
+                    'L' => array(
+                        'content' => $left_content,
+                        'font-size' => 10,
+                        'font-style' => 'B',
+                        'font-family' => 'serif',
+                        'color'=>'#000000'
+                    ),
+                    'C' => array(
+                        'content' => $center_content,
+                        'font-size' => 10,
+                        'font-style' => 'B',
+                        'font-family' => 'serif',
+                        'color'=>'#000000'
+                    ),
+                    'R' => array(
+                        'content' => $right_content,
+                        'font-size' => 10,
+                        'font-style' => 'B',
+                        'font-family' => 'serif',
+                        'color'=>'#000000'
+                    ),
+                    'line' => 1,
+                ),
             );
             $this->pdf->SetHeader($header);// ('{DATE j-m-Y}|{PAGENO}/{nb}|'.$title);
         }
     }
 
-    public function set_custom_header($header) {
+    /**
+     * @param string $header html content
+     */
+    public function set_custom_header($header)
+    {
         $this->custom_header = $header;
     }
 
-    public function set_custom_footer($footer) {
+    /**
+     * @param string $footer html content
+     */
+    public function set_custom_footer($footer)
+    {
         $this->custom_footer = $footer;
     }
 
@@ -565,7 +607,7 @@ class PDF
             error_log('Asked with no decoration');
         }
         $course_code = null;
-        if (!empty( $course_data)) {
+        if (!empty($course_data)) {
             $course_code = $course_data['code'];
         }
 
@@ -576,7 +618,8 @@ class PDF
         */
         $this->pdf->directionality      = api_get_text_direction(); // TODO: To be read from the html document.
         $this->pdf->useOnlyCoreFonts    = true;
-        $this->pdf->mirrorMargins       = 1;            // Use different Odd/Even headers and footers and mirror margins
+        // Use different Odd/Even headers and footers and mirror margins
+        $this->pdf->mirrorMargins       = 1;
 
         // Add decoration only if not stated otherwise
         if ($complete) {

+ 27 - 12
main/inc/lib/sessionmanager.lib.php

@@ -1540,9 +1540,8 @@ class SessionManager
     * Subscribes sessions to human resource manager (Dashboard feature)
     * @param	int 		Human Resource Manager id
     * @param	array 		Sessions id
-    * @param	int			Relation type
     **/
-	public static function suscribe_sessions_to_hr_manager($hr_manager_id,$sessions_list)
+	public static function suscribe_sessions_to_hr_manager($hr_manager_id, $sessions_list)
     {
         // Database Table Definitions
         $tbl_session_rel_user           =   Database::get_main_table(TABLE_MAIN_SESSION_USER);
@@ -1553,24 +1552,36 @@ class SessionManager
 
         // Deleting assigned sessions to hrm_id
         if (api_is_multiple_url_enabled()) {
-            $sql = "SELECT id_session FROM $tbl_session_rel_user s INNER JOIN $tbl_session_rel_access_url a ON (a.session_id = s.id_session) WHERE id_user = $hr_manager_id AND relation_type=".SESSION_RELATION_TYPE_RRHH." AND access_url_id = ".api_get_current_access_url_id()."";
+            $sql = "SELECT id_session
+                    FROM $tbl_session_rel_user s
+                    INNER JOIN $tbl_session_rel_access_url a ON (a.session_id = s.id_session)
+                    WHERE
+                        id_user = $hr_manager_id AND
+                        relation_type=".SESSION_RELATION_TYPE_RRHH." AND
+                        access_url_id = ".api_get_current_access_url_id()."";
         } else {
-            $sql = "SELECT id_session FROM $tbl_session_rel_user s WHERE id_user = $hr_manager_id AND relation_type=".SESSION_RELATION_TYPE_RRHH."";
+            $sql = "SELECT id_session FROM $tbl_session_rel_user s
+                    WHERE id_user = $hr_manager_id AND relation_type=".SESSION_RELATION_TYPE_RRHH."";
         }
         $result = Database::query($sql);
 
         if (Database::num_rows($result) > 0) {
             while ($row = Database::fetch_array($result))   {
-                 $sql = "DELETE FROM $tbl_session_rel_user WHERE id_session = {$row['id_session']} AND id_user = $hr_manager_id AND relation_type=".SESSION_RELATION_TYPE_RRHH." ";
+                 $sql = "DELETE FROM $tbl_session_rel_user
+                        WHERE
+                            id_session = {$row['id_session']} AND
+                            id_user = $hr_manager_id AND
+                            relation_type=".SESSION_RELATION_TYPE_RRHH." ";
                  Database::query($sql);
             }
         }
 
-		// inserting new sessions list
+		// Inserting new sessions list
 		if (is_array($sessions_list)) {
 			foreach ($sessions_list as $session_id) {
 				$session_id = intval($session_id);
-				$insert_sql = "INSERT IGNORE INTO $tbl_session_rel_user(id_session, id_user, relation_type) VALUES($session_id, $hr_manager_id, '".SESSION_RELATION_TYPE_RRHH."')";
+				$insert_sql = "INSERT IGNORE INTO $tbl_session_rel_user(id_session, id_user, relation_type) VALUES
+				               ($session_id, $hr_manager_id, '".SESSION_RELATION_TYPE_RRHH."')";
 				Database::query($insert_sql);
 				$affected_rows = Database::affected_rows();
 			}
@@ -2060,8 +2071,7 @@ class SessionManager
         $daysCoachAccessAfterBeginning = null,
         $sessionVisibility = 1,
         $fieldsToAvoidUpdate = array()
-    )
-    {
+    ) {
         $content = file($file);
 
         $error_message = null;
@@ -2280,11 +2290,16 @@ class SessionManager
                             }
                         }
 
-                        Database::query("DELETE FROM $tbl_session_user WHERE id_session='$session_id'");
-                        Database::query("DELETE FROM $tbl_session_course WHERE id_session='$session_id'");
+                        $sql = "DELETE FROM $tbl_session_user
+                                WHERE id_session = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
+                        Database::query($sql);
+
+                        $sql = "DELETE FROM $tbl_session_course WHERE id_session = '$session_id'";
+                        Database::query($sql);
 
                         // Delete session course user relation ships *only* for students
-                        Database::query("DELETE FROM $tbl_session_course_user WHERE id_session='$session_id' AND status <> 2");
+                        $sql = "DELETE FROM $tbl_session_course_user WHERE id_session = '$session_id' AND status <> 2";
+                        Database::query($sql);
                     }
                     $session_counter++;
                 }

+ 3 - 1
main/inc/lib/social.lib.php

@@ -594,7 +594,9 @@ class SocialManager extends UserManager
             $html .= '<div class="well social-background-content">';
             $html .= Display::url('<img src='.$big['file'].' class="social-groups-image" /> </a><br /><br />', api_get_path(WEB_PATH).'main/social/groups.php?id='.$group_id);
             if (GroupPortalManager::is_group_admin($group_id, api_get_user_id())) {
-                $html .= '<div id="edit_image" class="hidden_message" style="display:none"><a href="'.api_get_path(WEB_PATH).'main/social/group_edit.php?id='.$group_id.'">'.get_lang('EditGroup').'</a></div>';
+                $html .= '<div id="edit_image" class="hidden_message" style="display:none">
+                            <a href="'.api_get_path(WEB_PATH).'main/social/group_edit.php?id='.$group_id.'">'.
+                    get_lang('EditGroup').'</a></div>';
             }
             $html .= '</div>';
             $html .= '</div>';

+ 2 - 2
main/inc/lib/tracking.lib.php

@@ -3574,7 +3574,7 @@ class TrackingCourseLog
 
     	if (!empty($_GET['user_keyword'])) {
     		$keyword = trim(Database::escape_string($_GET['user_keyword']));
-    		$condition_user .=  " AND  (user.firstname LIKE '%".$keyword."%' OR user.lastname LIKE '%".$keyword."%'  OR user.username LIKE '%".$keyword."%'  OR user.email LIKE '%".$keyword."%' ) ";
+    		$condition_user .=  " AND (user.firstname LIKE '%".$keyword."%' OR user.lastname LIKE '%".$keyword."%'  OR user.username LIKE '%".$keyword."%'  OR user.email LIKE '%".$keyword."%' ) ";
     	}
 
     	if (api_is_multiple_url_enabled()) {
@@ -3638,7 +3638,7 @@ class TrackingCourseLog
     		$user['official_code']  = $user['col0'];
             $user['lastname']       = $user['col1'];
             $user['firstname']      = $user['col2'];
-    		$user['username']        = $user['col3'];
+    		$user['username']       = $user['col3'];
     		$user['time'] = api_time_to_hms(Tracking::get_time_spent_on_the_course($user['user_id'], $course_code, $session_id));
 
     		$avg_student_score = Tracking::get_avg_student_score($user['user_id'], $course_code, array(), $session_id);

+ 158 - 17
main/inc/lib/urlmanager.lib.php

@@ -264,6 +264,37 @@ class UrlManager
         return $courses;
     }
 
+    /**
+     * Gets the inner join of access_url and the usergroup table
+     *
+     * @author Julio Montoya
+     * @param int  access url id
+     * @return array   Database::store_result of the result
+     **/
+
+    public static function getUrlRelCourseCategory($access_url_id = null)
+    {
+
+        $table_url_rel = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
+        $where = " WHERE 1=1 ";
+        if (!empty($access_url_id)) {
+            $where .= " AND $table_url_rel.access_url_id = ".intval($access_url_id);
+        }
+        $where .= " AND (parent_id IS NULL) ";
+
+        $sql = "SELECT id, name, access_url_id
+            FROM $table u
+            INNER JOIN $table_url_rel
+            ON $table_url_rel.course_category_id = u.id
+            $where
+            ORDER BY name";
+
+        $result = Database::query($sql);
+        $courses = Database::store_result($result, 'ASSOC');
+        return $courses;
+    }
+
     /**
      * Sets the status of an URL 1 or 0
      * @author Julio Montoya
@@ -500,22 +531,6 @@ class UrlManager
         return $num;
     }
 
-    /**
-     * @param int $categoryCourseId
-     * @param int $urlId
-     * @return int
-     */
-    public static function addCourseCategoryToUrl($categoryCourseId, $urlId)
-    {
-        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
-        $sql = "INSERT INTO $table SET
-                course_category_id = '".intval($categoryCourseId)."',
-                access_url_id = ".intval($urlId);
-        Database::query($sql);
-        return Database::insert_id();
-    }
-
-
     /**
      * @param int $userGroupId
      * @param int $urlId
@@ -532,6 +547,27 @@ class UrlManager
         return Database::insert_id();
     }
 
+    /**
+     * @param int $categoryId
+     * @param int $urlId
+     * @return int
+     */
+    public static function addCourseCategoryToUrl($categoryId, $urlId)
+    {
+        $exists = self::relationUrlCourseCategoryExist($categoryId, $urlId);
+        if (empty($exists)) {
+            $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+
+            $sql = "INSERT INTO $table
+                    SET
+                    course_category_id = '".intval($categoryId)."',
+                    access_url_id = ".intval($urlId);
+            Database::query($sql);
+
+            return Database::insert_id();
+        }
+        return 0;
+    }
 
     /**
      * Add a group of sessions into a group of URLs
@@ -618,7 +654,7 @@ class UrlManager
             $url_id=1;
         }
         $result = false;
-        $count = UrlManager::relation_url_session_exist($session_id,$url_id);
+        $count = UrlManager::relation_url_session_exist($session_id, $url_id);
         $session_id	= intval($session_id);
         if (empty($count) && !empty($session_id)) {
             $url_id = intval($url_id);
@@ -680,6 +716,24 @@ class UrlManager
         return $result;
     }
 
+    /**
+     * Deletes an url and $userGroup relationship
+     * @author Julio Montoya
+     * @param  int $userGroupId
+     * @param  int $urlId
+     * @return boolean true if success
+     * */
+    public static function deleteUrlRelCourseCategory($userGroupId, $urlId)
+    {
+        $table = Database :: get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+        $sql= "DELETE FROM $table
+               WHERE course_category_id = '".intval($userGroupId)."' AND
+                     access_url_id=".intval($urlId)."  ";
+        $result = Database::query($sql);
+        return $result;
+    }
+
+
 
     /**
     * Deletes an url and session relationship
@@ -813,6 +867,55 @@ class UrlManager
         }
     }
 
+    /**
+     * Updates the access_url_rel_course_category table with a given list
+     * @author Julio Montoya
+     * @param array course category list
+     * @param int access_url_id
+     **/
+    public static function updateUrlRelCourseCategory($list, $urlId)
+    {
+        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
+
+        $sql = "SELECT course_category_id FROM $table WHERE access_url_id = ".intval($urlId);
+        $result = Database::query($sql);
+        $existingItems = array();
+
+        while ($row = Database::fetch_array($result)){
+            $existingItems[] = $row['course_category_id'];
+        }
+
+        // Adding
+
+        foreach ($list as $id) {
+            UrlManager::addCourseCategoryToUrl($id, $urlId);
+            $categoryInfo = getCategoryById($id);
+            $children = getChildren($categoryInfo['code']);
+            if (!empty($children)) {
+                foreach ($children as $category) {
+                    UrlManager::addCourseCategoryToUrl($category['id'], $urlId);
+                }
+            }
+        }
+
+        // Deleting old items
+        foreach ($existingItems as $id) {
+            if (!in_array($id, $list)) {
+                UrlManager::deleteUrlRelCourseCategory($id, $urlId);
+                $categoryInfo = getCategoryById($id);
+
+                $children = getChildren($categoryInfo['code']);
+                if (!empty($children)) {
+                    foreach ($children as $category) {
+                        UrlManager::deleteUrlRelCourseCategory($category['id'], $urlId);
+                    }
+                }
+            }
+        }
+    }
+
+
+
     /**
      * Updates the access_url_rel_session table with a given user list
      * @author Julio Montoya
@@ -894,4 +997,42 @@ class UrlManager
         $access_url_id = Database::result($result, 0, 0);
         return $access_url_id;
     }
+
+    /**
+     *
+     * @param string $needle
+     * @return XajaxResponse
+     */
+    public static function searchCourseCategoryAjax($needle)
+    {
+        $response = new XajaxResponse();
+        $return = '';
+
+        if (!empty($needle)) {
+            // xajax send utf8 datas... datas in db can be non-utf8 datas
+            $charset = api_get_system_encoding();
+            $needle = api_convert_encoding($needle, $charset, 'utf-8');
+            $needle = Database::escape_string($needle);
+            // search courses where username or firstname or lastname begins likes $needle
+            $sql = 'SELECT id, name FROM '.Database::get_main_table(TABLE_MAIN_CATEGORY).' u
+                    WHERE name LIKE "'.$needle.'%" AND (parent_id IS NULL or parent_id = 0)
+                    ORDER BY name
+                    LIMIT 11';
+            $result = Database::query($sql);
+            $i = 0;
+            while ($data = Database::fetch_array($result)) {
+                $i++;
+                if ($i <= 10) {
+                    $return .= '<a
+                    href="javascript: void(0);"
+                    onclick="javascript: add_user_to_url(\''.addslashes($data['id']).'\',\''.addslashes($data['name']).' \')">'.$data['name'].' </a><br />';
+                } else {
+                    $return .= '...<br />';
+                }
+            }
+        }
+        $response->addAssign('ajax_list_courses', 'innerHTML', api_utf8_encode($return));
+        return $response;
+    }
+
 }

+ 17 - 10
main/newscorm/lp_upload.php

@@ -20,7 +20,6 @@ if (empty($_POST['current_dir'])) {
 }
 $uncompress = 1;
 
-//error_log('New LP - lp_upload.php', 0);
 /*
  * Check the request method in place of a variable from POST
  * because if the file size exceed the maximum file upload
@@ -30,7 +29,7 @@ $uncompress = 1;
 $user_file = Request::is_post() ? Request::file('user_file') : array();
 $user_file = $user_file ? $user_file : array();
 $is_error = isset($user_file['error']) ? $user_file['error'] : false;
-if( Request::is_post() && $is_error){
+if (Request::is_post() && $is_error) {
     return api_failure::set_failure('upload_file_too_big');
     unset($_FILEs['user_file']);
 } else if ($_SERVER['REQUEST_METHOD'] == 'POST' && count($_FILES) > 0 && !empty($_FILES['user_file']['name'])) {
@@ -55,11 +54,11 @@ if( Request::is_post() && $is_error){
 
     $proximity = 'local';
     if (!empty($_REQUEST['content_proximity'])) {
-    	$proximity = Database::escape_string($_REQUEST['content_proximity']);
+        $proximity = Database::escape_string($_REQUEST['content_proximity']);
     }
     $maker = 'Scorm';
     if (!empty($_REQUEST['content_maker'])) {
-    	$maker = Database::escape_string($_REQUEST['content_maker']);
+        $maker = Database::escape_string($_REQUEST['content_maker']);
     }
 
     switch ($type) {
@@ -108,7 +107,7 @@ if( Request::is_post() && $is_error){
         default:
             return api_failure::set_failure('not_a_learning_path');
     }
-} elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
+} elseif ($_SERVER['REQUEST_METHOD'] == 'POST') {
     // end if is_uploaded_file
 
     // If file name given to get in claroline/upload/, try importing this way.
@@ -142,7 +141,7 @@ if( Request::is_post() && $is_error){
             require_once 'scorm.class.php';
             $oScorm = new scorm();
             $manifest = $oScorm->import_local_package($s, $current_dir);
-            if ($manifest === false ) { //if ap i_set_failure
+            if ($manifest === false) { //if ap i_set_failure
                 return api_failure::set_failure(api_failure::get_last_failure());
             }
             if (!empty($manifest)) {
@@ -151,9 +150,13 @@ if( Request::is_post() && $is_error){
             }
 
             $proximity = '';
-            if (!empty($_REQUEST['content_proximity'])) { $proximity = Database::escape_string($_REQUEST['content_proximity']); }
+            if (!empty($_REQUEST['content_proximity'])) {
+                $proximity = Database::escape_string($_REQUEST['content_proximity']);
+            }
             $maker = '';
-            if (!empty($_REQUEST['content_maker'])) {$maker = Database::escape_string($_REQUEST['content_maker']); }
+            if (!empty($_REQUEST['content_maker'])) {
+                $maker = Database::escape_string($_REQUEST['content_maker']);
+            }
             $oScorm->set_proximity($proximity);
             $oScorm->set_maker($maker);
             $oScorm->set_jslib('scorm_api.php');
@@ -167,9 +170,13 @@ if( Request::is_post() && $is_error){
                 $oAICC->import_aicc(api_get_course_id());
             }
             $proximity = '';
-            if (!empty($_REQUEST['content_proximity'])) { $proximity = Database::escape_string($_REQUEST['content_proximity']); }
+            if (!empty($_REQUEST['content_proximity'])) {
+                $proximity = Database::escape_string($_REQUEST['content_proximity']);
+            }
             $maker = '';
-            if (!empty($_REQUEST['content_maker'])) { $maker = Database::escape_string($_REQUEST['content_maker']); }
+            if (!empty($_REQUEST['content_maker'])) {
+                $maker = Database::escape_string($_REQUEST['content_maker']);
+            }
             $oAICC->set_proximity($proximity);
             $oAICC->set_maker($maker);
             $oAICC->set_jslib('aicc_api.php');

+ 26 - 18
main/newscorm/openoffice_document.class.php

@@ -7,13 +7,15 @@
  * to help in the conversion of Office documents to learning paths
  * @package chamilo.learnpath
  * @author	Eric Marguin <eric.marguin@dokeos.com>
+ * @author Julio Montoya
  * @license	GNU/GPL
  */
 
 /**
  * Defines the "OpenofficeDocument" child of class "learnpath"
  */
-abstract class OpenofficeDocument extends learnpath {
+abstract class OpenofficeDocument extends learnpath
+{
 
     public $first_item = 0;
     public $original_charset = 'utf-8';
@@ -25,31 +27,36 @@ abstract class OpenofficeDocument extends learnpath {
      * @param	integer	Learnpath ID in DB
      * @param	integer	User ID
      */
-    public function __construct($course_code = null, $resource_id = null, $user_id = null) {
+    public function __construct($course_code = null, $resource_id = null, $user_id = null)
+    {
         if ($this->debug > 0) {
             error_log('In OpenofficeDocument::OpenofficeDocument()', 0);
         }
         if (!empty($course_code) && !empty($resource_id) && !empty($user_id)) {
             parent::__construct($course_code, $resource_id, $user_id);
-        } else {
-            // Do nothing but still build the presentation object.
         }
     }
 
-    public function convert_document($file, $action_after_conversion = 'make_lp') {
-        global $_course, $_user, $_configuration;
-        $this->file_name = pathinfo($file['name'], PATHINFO_FILENAME);        
+    /**
+     * @param string $file
+     * @param string $action_after_conversion
+     * @return bool|int
+     */
+    public function convert_document($file, $action_after_conversion = 'make_lp')
+    {
+        global $_course;
+        $this->file_name = pathinfo($file['name'], PATHINFO_FILENAME);
         // Create the directory
-        $result = $this->generate_lp_folder($_course, $this->file_name);                        
-                
+        $result = $this->generate_lp_folder($_course, $this->file_name);
+
          // Create the directory
         $this->base_work_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
         ///learning_path/ppt_dirname directory
-        $this->created_dir = substr($result['dir'], 0, strlen($result['dir']) -1);        
+        $this->created_dir = substr($result['dir'], 0, strlen($result['dir']) -1);
         $this->file_path = $this->created_dir.'/'.replace_dangerous_char($file['name'], 'strict');
-        
+
         //var_dump($this->file_name, $this->file_path, $this->base_work_dir, $this->created_dir);
-    
+
         /*
          * Original code
         global $_course, $_user, $_configuration;
@@ -69,9 +76,9 @@ abstract class OpenofficeDocument extends learnpath {
         $this->base_work_dir = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
 
         $this->created_dir = create_unexisting_directory($_course, $_user['user_id'], api_get_session_id(), 0, 0, $this->base_work_dir, $dir_name);
-       
+
             var_dump($this->file_name, $this->file_path, $this->base_work_dir, $this->created_dir);
-        
+
         */
 
         $ppt2lp_host = api_get_setting('service_ppt2lp', 'host');
@@ -96,7 +103,7 @@ abstract class OpenofficeDocument extends learnpath {
             $cmd .= ' -p ' . api_get_setting('service_ppt2lp', 'port');
             // Call to the function implemented by child.
             $cmd .= $this->add_command_parameters();
-            // To allow openoffice to manipulate docs.            
+            // To allow openoffice to manipulate docs.
             @chmod($this->base_work_dir, 0777);
             @chmod($this->base_work_dir.$this->created_dir, 0777);
             @chmod($this->base_work_dir.$this->file_path, 0777);
@@ -107,7 +114,7 @@ abstract class OpenofficeDocument extends learnpath {
             $files = array();
             $return = 0;
             $shell = exec($cmd, $files, $return);
-            
+
             if ($return != 0) { // If the java application returns an error code.
                 switch ($return) {
                     // Can't connect to openoffice.
@@ -141,7 +148,7 @@ abstract class OpenofficeDocument extends learnpath {
             // files info
             $files = $result['files'];
         }
-        
+
         if (!empty($files)) {
             // Create lp
             $this->lp_id = learnpath::add_lp($_course['id'], $this->file_name, '', 'guess', 'manual');
@@ -165,7 +172,8 @@ abstract class OpenofficeDocument extends learnpath {
      * @param   array current ppt file
      * @return  array images files
      */
-    private function _get_remote_ppt2lp_files($file) {
+    private function _get_remote_ppt2lp_files($file)
+    {
         require_once api_get_path(LIBRARY_PATH) . 'nusoap/nusoap.php';
         // host
         $ppt2lp_host = api_get_setting('service_ppt2lp', 'host');

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

@@ -20,17 +20,19 @@ if (api_get_setting('search_enabled') == 'true') {
     require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
 }
 
-class OpenofficePresentation extends OpenofficeDocument {
+class OpenofficePresentation extends OpenofficeDocument
+{
 
     public $take_slide_name;
 
-    public function __construct($take_slide_name = false, $course_code = null, $resource_id = null, $user_id = null) {
+    public function __construct($take_slide_name = false, $course_code = null, $resource_id = null, $user_id = null)
+    {
         $this->take_slide_name = $take_slide_name;
         parent::__construct($course_code, $resource_id, $user_id);
     }
 
-
-    public function make_lp($files = array()) {
+    public function make_lp($files = array())
+    {
         global $_course;
         $previous = 0;
         $i = 0;
@@ -39,8 +41,10 @@ class OpenofficePresentation extends OpenofficeDocument {
             return false;
 
         foreach ($files as $file) {
-
-            list($slide_name, $file_name, $slide_body) = explode('||', $file); // '||' is used as separator between fields: slide name (with accents) || file name (without accents) || all slide text (to be indexed).
+            /* '||' is used as separator between fields:
+                slide name (with accents) || file name (without accents) || all slide text (to be indexed).
+            */
+            list($slide_name, $file_name, $slide_body) = explode('||', $file);
 
             // Filename is utf8 encoded, but when we decode, some chars are not translated (like quote &rsquo;).
             // so we remove these chars by translating it in htmlentities and the reconvert it in want charset.
@@ -58,8 +62,26 @@ class OpenofficePresentation extends OpenofficeDocument {
 
             $i++;
             // Add the png to documents.
-            $document_id = add_document($_course, $this->created_dir.'/'.urlencode($file_name), 'file', filesize($this->base_work_dir.$this->created_dir.'/'.$file_name), $slide_name);
-            api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', api_get_user_id(), 0, 0, null, null, api_get_session_id());
+            $document_id = add_document(
+                $_course,
+                $this->created_dir.'/'.urlencode($file_name),
+                'file',
+                filesize($this->base_work_dir.$this->created_dir.'/'.$file_name),
+                $slide_name
+            );
+
+            api_item_property_update(
+                $_course,
+                TOOL_DOCUMENT,
+                $document_id,
+                'DocumentAdded',
+                api_get_user_id(),
+                0,
+                0,
+                null,
+                null,
+                api_get_session_id()
+            );
 
             // Generating the thumbnail.
             $image = $this->base_work_dir.$this->created_dir .'/'. $file_name;
@@ -67,21 +89,28 @@ class OpenofficePresentation extends OpenofficeDocument {
             $pattern = '/(\w+)\.png$/';
             $replacement = '${1}_thumb.png';
             $thumb_name = preg_replace($pattern, $replacement, $file_name);
-            
+
             // Calculate thumbnail size.
             $image_size = api_getimagesize($image);
             $width  = $image_size['width'];
             $height = $image_size['height'];
-            
+
             $thumb_width = 300;
             $thumb_height = floor($height * ($thumb_width / $width));
-  
+
             $my_new_image = new Image($image);
             $my_new_image->resize($thumb_width, $thumb_height);
             $my_new_image->send_image($this->base_work_dir.$this->created_dir .'/'. $thumb_name, -1, 'png');
-  
+
             // Adding the thumbnail to documents.
-            $document_id_thumb = add_document($_course, $this->created_dir.'/'.urlencode($thumb_name), 'file', filesize($this->base_work_dir.$this->created_dir.'/'.$thumb_name), $slide_name);
+            $document_id_thumb = add_document(
+                $_course,
+                $this->created_dir.'/'.urlencode($thumb_name),
+                'file',
+                filesize($this->base_work_dir.$this->created_dir.'/'.$thumb_name),
+                $slide_name
+            );
+
             api_item_property_update($_course, TOOL_THUMBNAIL, $document_id_thumb, 'DocumentAdded', api_get_user_id(), 0, 0);
 
             // Create an html file.
@@ -100,7 +129,14 @@ class OpenofficePresentation extends OpenofficeDocument {
 </html>');  // This indentation is to make the generated html files to look well.
 
             fclose($fp);
-            $document_id = add_document($_course,$this->created_dir.'/'.urlencode($html_file), 'file', filesize($this->base_work_dir.$this->created_dir.'/'.$html_file), $slide_name);
+            $document_id = add_document(
+                $_course,
+                $this->created_dir.'/'.urlencode($html_file),
+                'file',
+                filesize($this->base_work_dir.$this->created_dir.'/'.$html_file),
+                $slide_name
+            );
+
             if ($document_id) {
 
                 // Put the document in item_property update.
@@ -114,7 +150,7 @@ class OpenofficePresentation extends OpenofficeDocument {
             // Code for text indexing.
             if (api_get_setting('search_enabled') == 'true') {
 
-                if (isset($_POST['index_document']) && $_POST['index_document']) {                    
+                if (isset($_POST['index_document']) && $_POST['index_document']) {
                     $di = new ChamiloIndexer();
                     isset($_POST['language']) ? $lang = Database::escape_string($_POST['language']) : $lang = 'english';
                     $di->connectDb(NULL, NULL, $lang);
@@ -165,18 +201,22 @@ class OpenofficePresentation extends OpenofficeDocument {
         }
     }
 
-    function add_command_parameters() {
-        if (empty($this->slide_width) || empty($this->slide_height))
+    function add_command_parameters()
+    {
+        if (empty($this->slide_width) || empty($this->slide_height)) {
             list($this->slide_width, $this->slide_height) = explode('x', api_get_setting('service_ppt2lp', 'size'));
+        }
         return ' -w '.$this->slide_width.' -h '.$this->slide_height.' -d oogie "'.$this->base_work_dir.'/'.$this->file_path.'"  "'.$this->base_work_dir.$this->created_dir.'.html"';
     }
 
-    function set_slide_size($width, $height) {
+    function set_slide_size($width, $height)
+    {
         $this->slide_width = $width;
         $this->slide_height = $height;
     }
 
-    function add_docs_to_visio($files = array()) {
+    function add_docs_to_visio($files = array())
+    {
         global $_course;
         foreach ($files as $file) {
             list($slide_name,$file_name) = explode('||',$file); // '||' is used as separator between slide name (with accents) and file name (without accents).

+ 48 - 50
main/upload/upload_ppt.php

@@ -11,7 +11,7 @@
  */
 
 //the document file is loaded because most of the upload vocab relates to the document tool
-$language_file[] = "document"; 
+$language_file[] = "document";
 $language_file[] = "learnpath";
 $language_file[] = "scormdocument";
 
@@ -26,39 +26,41 @@ $htmlHeadXtra[] = '<script type="text/javascript">
 	var myUpload = new upload(0);
 </script>';
 
-if (isset($_POST['convert'])){
-	$cwdir = getcwd();
-	if(isset($_FILES['user_file'])) {
-		$allowed_extensions = array('odp','sxi','ppt','pps','sxd','pptx');
-		if(in_array(strtolower(pathinfo($_FILES['user_file']['name'],PATHINFO_EXTENSION)),$allowed_extensions)) {
-			require('../newscorm/lp_upload.php');
-			if(isset($o_ppt) && $first_item_id != 0){
-				if (api_get_setting('search_enabled')=='true') {
-                    require_once(api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php');
+if (isset($_POST['convert'])) {
+    $cwdir = getcwd();
+    if (isset($_FILES['user_file'])) {
+        $allowed_extensions = array('odp', 'sxi', 'ppt', 'pps', 'sxd', 'pptx');
+        if (in_array(strtolower(pathinfo($_FILES['user_file']['name'], PATHINFO_EXTENSION)), $allowed_extensions)) {
+            require_once api_get_path(SYS_CODE_PATH).'newscorm/lp_upload.php';
+            if (isset($o_ppt) && $first_item_id != 0) {
+                if (api_get_setting('search_enabled')=='true') {
+                    require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php';
                     $specific_fields = get_specific_field_list();
                     foreach ($specific_fields as $specific_field) {
-    					$values = explode(',', trim($_POST[$specific_field['code']]));
-    					if ( !empty($values) ) {
-    						foreach ($values as $value) {
-    							$value = trim($value);
-    							if ( !empty($value) ) {
-    								add_specific_field_value($specific_field['id'], api_get_course_id(), TOOL_LEARNPATH, $o_ppt->lp_id, $value);
-    							}
-    						}
-    					}
-    				}
+                        $values = explode(',', trim($_POST[$specific_field['code']]));
+                        if (!empty($values)) {
+                            foreach ($values as $value) {
+                                $value = trim($value);
+                                if (!empty($value)) {
+                                    add_specific_field_value($specific_field['id'], api_get_course_id(), TOOL_LEARNPATH, $o_ppt->lp_id, $value);
+                                }
+                            }
+                        }
+                    }
                 }
-				header('Location: ../newscorm/lp_controller.php?'.api_get_cidreq().'&lp_id='.$o_ppt->lp_id.'&action=view_item&id='.$first_item_id);
-			} else {
-				if(!empty($o_ppt->error))
-					$errorMessage = $o_ppt->error;
-				else
-					$errorMessage = get_lang('OogieUnknownError');
-			}
-		} else {
-			$errorMessage = get_lang('OogieBadExtension');
-		}
-	}
+                header('Location: ../newscorm/lp_controller.php?'.api_get_cidreq().'&lp_id='.$o_ppt->lp_id.'&action=view_item&id='.$first_item_id);
+                exit;
+            } else {
+                if (!empty($o_ppt->error)) {
+                    $errorMessage = $o_ppt->error;
+                } else {
+                    $errorMessage = get_lang('OogieUnknownError');
+                }
+            }
+        } else {
+            $errorMessage = get_lang('OogieBadExtension');
+        }
+    }
 }
 
 event_access_tool(TOOL_UPLOAD);
@@ -66,8 +68,8 @@ event_access_tool(TOOL_UPLOAD);
 // check access permissions (edit permission is needed to add a document or a LP)
 $is_allowed_to_edit = api_is_allowed_to_edit();
 
-if(!$is_allowed_to_edit){
-	api_not_allowed(true);
+if (!$is_allowed_to_edit) {
+    api_not_allowed(true);
 }
 
 $interbreadcrumb[]= array ("url"=>"../newscorm/lp_controller.php?action=list", "name"=> get_lang("Doc"));
@@ -76,38 +78,34 @@ $nameTools = get_lang("OogieConversionPowerPoint");
 Display :: display_header($nameTools);
 $message = get_lang("WelcomeOogieConverter");
 
-
-
-if (!empty($errorMessage)) {	
+if (!empty($errorMessage)) {
     echo Display::return_message($errorMessage, 'warning', false);
 }
 
+$div_upload_limit = get_lang('UploadMaxSize').' : '.ini_get('post_max_size');
+
 $form = new FormValidator('upload_ppt', 'POST', '', '');
 $form->addElement('header', get_lang("WelcomeOogieSubtitle"));
-
 $form->addElement('html', Display::return_message($message, 'info', false));
-
-// build the form
-$div_upload_limit = get_lang('UploadMaxSize').' : '.ini_get('post_max_size');
-$form->addElement ('file', 'user_file', array('<img src="../img/powerpoint_big.gif" />', $div_upload_limit));
-$form->addElement ('checkbox', 'take_slide_name','', get_lang('TakeSlideName'));
-if (api_get_setting('search_enabled')=='true') {
+$form->addElement('file', 'user_file', array('<img src="../img/powerpoint_big.gif" />', $div_upload_limit));
+$form->addElement('checkbox', 'take_slide_name', '', get_lang('TakeSlideName'));
+if (api_get_setting('search_enabled') == 'true') {
     require_once(api_get_path(LIBRARY_PATH) . 'specific_fields_manager.lib.php');
     $specific_fields = get_specific_field_list();
-    $form->addElement ('checkbox', 'index_document','', get_lang('SearchFeatureDoIndexDocument'));        
-    $form->addElement ('select_language', 'language', get_lang('SearchFeatureDocumentLanguage'));    
+    $form->addElement('checkbox', 'index_document', '', get_lang('SearchFeatureDoIndexDocument'));
+    $form->addElement('select_language', 'language', get_lang('SearchFeatureDocumentLanguage'));
     foreach ($specific_fields as $specific_field) {
-        $form->addElement ('text', $specific_field['code'], $specific_field['name'].' : ');
+        $form->addElement('text', $specific_field['code'], $specific_field['name'].' : ');
     }
 }
 
-$form->addElement ('style_submit_button', 'convert', get_lang('ConvertToLP'));
-$form->addElement ('hidden', 'ppt2lp', 'true');
+$form->addElement('style_submit_button', 'convert', get_lang('ConvertToLP'));
+$form->addElement('hidden', 'ppt2lp', 'true');
 
-$form->add_real_progress_bar(md5(rand(0,10000)), 'user_file', 1, true);
+$form->add_real_progress_bar(md5(rand(0, 10000)), 'user_file', 1, true);
 $defaults = array('take_slide_name'=>'checked="checked"','index_document'=>'checked="checked"');
 $form->setDefaults($defaults);
 
 // display the form
 $form->display();
-Display::display_footer();
+Display::display_footer();

+ 7 - 5
main/work/add_document.php

@@ -6,7 +6,6 @@ use ChamiloSession as Session;
 $language_file = array('exercice', 'work', 'document', 'admin', 'gradebook');
 
 require_once '../inc/global.inc.php';
-// Including necessary files
 require_once 'work.lib.php';
 
 if (ADD_DOCUMENT_TO_WORK == false) {
@@ -18,6 +17,7 @@ $current_course_tool  = TOOL_STUDENTPUBLICATION;
 $workId = isset($_GET['id']) ? intval($_GET['id']) : null;
 $docId = isset($_GET['document_id']) ? intval($_GET['document_id']) : null;
 $action = isset($_GET['action']) ? $_GET['action'] : null;
+$message = isset($_GET['message']) ? Security::remove_XSS($_GET['message']) : null;
 
 if (empty($workId)) {
     api_not_allowed(true);
@@ -56,6 +56,7 @@ switch ($action) {
 if (empty($docId)) {
 
     Display :: display_header(null);
+    echo $message;
     $documents = getAllDocumentToWork($workId, api_get_course_int_id());
     if (!empty($documents)) {
         echo Display::page_subheader(get_lang('DocumentsAdded'));
@@ -86,7 +87,6 @@ if (empty($docId)) {
     echo $document_tree;
     echo '<hr /><div class="clear"></div>';
 } else {
-    $message = null;
 
     $documentInfo = DocumentManager::get_document_data_by_id($docId, $courseInfo['code']);
     $url = api_get_path(WEB_CODE_PATH).'work/add_document.php?id='.$workId.'&document_id='.$docId.'&'.api_get_cidreq();
@@ -105,12 +105,14 @@ if (empty($docId)) {
 
         if (empty($data)) {
             addDocumentToWork($docId, $workId, api_get_course_int_id());
-            $url = api_get_path(WEB_CODE_PATH).'work/add_document.php?id='.$workId.'&'.api_get_cidreq();
-            header('Location: '.$url);
-            exit;
+            $message = Display::return_message(get_lang('Added'), 'success');
         } else {
             $message = Display::return_message(get_lang('DocumentAlreadyAdded'), 'warning');
         }
+
+        $url = api_get_path(WEB_CODE_PATH).'work/add_document.php?id='.$workId.'&'.api_get_cidreq().'&message='.$message;
+        header('Location: '.$url);
+        exit;
     }
 
     Display::display_header(null);