skala
Laurent Opprecht 14 years ago
commit 82bfd016bc
  1. 3
      documentation/changelog.html
  2. 101
      documentation/install_red5.txt
  3. 24
      main/calendar/agenda.lib.php
  4. 4
      main/calendar/agenda.php
  5. 57
      main/calendar/agenda_js.php
  6. 34
      main/css/base.css
  7. 14
      main/exercice/fill_blanks.class.php
  8. 8
      main/gradebook/gradebook_flatview.php
  9. 5
      main/gradebook/lib/fe/gradebooktable.class.php
  10. 81
      main/gradebook/lib/flatview_data_generator.class.php
  11. 114
      main/gradebook/lib/gradebook_functions.inc.php
  12. 48
      main/group/group_edit.php
  13. 51
      main/group/group_space.php
  14. 10
      main/inc/ajax/agenda.ajax.php
  15. 9
      main/inc/lib/display.lib.php
  16. 0
      main/inc/lib/fckeditor/editor/plugins/fckeditor_wiris/lang/en.js
  17. 0
      main/inc/lib/fckeditor/editor/plugins/fckeditor_wiris/lang/es.js
  18. 0
      main/inc/lib/fckeditor/editor/plugins/fckeditor_wiris/lang/fr.js
  19. 8
      main/inc/lib/grade_model.lib.php
  20. 46
      main/inc/lib/groupmanager.lib.php
  21. 3
      main/inc/lib/main_api.lib.php
  22. 6
      main/install/i_database.class.php
  23. 10
      main/lang/english/admin.inc.php
  24. 1
      main/lang/english/gradebook.inc.php
  25. 10
      main/lang/english/trad4all.inc.php
  26. 7
      main/lang/french/admin.inc.php
  27. 2
      main/lang/slovenian/trad4all.inc.php
  28. 4
      main/lang/slovenian/userInfo.inc.php
  29. 4
      main/lang/spanish/admin.inc.php
  30. 2
      main/lang/spanish/forum.inc.php
  31. 9
      main/lang/spanish/gradebook.inc.php
  32. 10
      main/lang/spanish/trad4all.inc.php
  33. 6
      main/template/default/agenda/month.tpl
  34. 3
      main/webservices/registration.soap.php

@ -41,7 +41,7 @@
</ul>
<h1>Chamilo&nbsp;Changelog</h1>
<h1>Chamilo 1.9.0 - [version-name], April 2012</h1>
<h1>Chamilo 1.9.0 alpha 5 - [version-name], April 2012</h1>
<h3>Release notes - summary</h3>
<p>Chamilo 1.9.0 is a major stable version with loads of added features.</p>
@ -213,6 +213,7 @@ This version of Chamilo only includes new features:
<h3>Removals</h3>
<ul>
<li>Removed deprecated "search" plugin (used to work with MnoGoSearch but hasn't been used for years to our knowledge - was successfully replaced by Xapian)</li>
<li>Removed the RED5 installation guide from the documentation directory: the supported BigBlueButton videoconference system provides its own installation manual, linked from the Chamilo admin guide.</li>
</ul>
<h1>Chamilo 1.8.8.4 - La Molina, August 2011</h1>

@ -1,101 +0,0 @@
Chamilo Red5 applications
========================
Table of contents
-----------------
1. Installation
1.1. Red5
1.2. Chamilo Red5 Application
2. Configuration
2.1. How does it work ?
2.2. Recorder
2.3. VideoConference
3. Known issues and improvments
==
1. Installation
1.1. Red5
To install red5, please check the documentation related to your platform on the red5 website[1]. Below, we will suppose that red5 home
directory is /opt/red5. If you run red5 under MS-Windows, change /opt/red5 by your installation directory, for example: D:\applications\red5.
From now on, we will refer to red5 home directory by $RED5_HOME.
[1] http://osflash.org/red5
1.2. Chamilo Red5 Application
To install either the recorder or the videoconference application, the only step that needs to be done is to copy the .war file in the $RED5_HOME/webapps directory.
You have to restart red5 to get the applications deployed inside red5. You can install both applications inside red5. They can run together
inside the same server without conflict.
2. Configuration
2.1. How does it work ?
War files are shipped with a bunch of default configuration files. Normally, you should never touch the files in the war file.
Upon startup, the applications are checking if any external configuration file can be found. If not, the application will be loading
the configuration files located in the war file, thus loading the default configuration.
Each application has one main configuration file that the administrator can customize. The location and the name of this configuration file can
be found in a resource file in the war file. This resource file is called either videoconference.propeties or recorder.properties.
One of the well-known issue here is that you have to recompile the application with other settings if you want to change
the configuration location and name. We will find a better solution for a future release.
The main configuration file is an XML file. Currently, there is no validation of this XML. It will probably be supported in a future release.
2.2. Recorder
The recorder configuration file is named recorder-config.xml. It has the following format:
<?xml version="1.0" encoding="UTF-8"?>
<recorder-config>
<video-streams-dir>/opt/dokeos/recorded-streams</video-streams-dir>
<vod-streams-dir>/opt/dokeos/vod-streams</vod-streams-dir>
</recorder-config>
video-streams-dir is the directory where the streams will be recorded.
vod-streams-dir is the directory where the streams will be found for playback.
We know the name of the parameters have not been chosen well. They will probably be changed in a future release.
2.3. Videoconference
The videoconference configuration file is named videoconference-config.xml. It has the following format:
<?xml version="1.0" encoding="UTF-8"?>
<videoconference-config>
<server-keys>
<server-key host="__test-cblue.dokeos.com_" key="0123456789abcdef0123456789abcdef" />
</server-keys>
<moderator-check-on-whiteboard>false</moderator-check-on-whiteboard>
<video-streams-dir>/opt/dokeos/recorded-streams</video-streams-dir>
<vod-streams-dir>/opt/dokeos/vod-streams</vod-streams-dir>
</videoconference-config>
server-keys contains a list of server-key tags.
A server-key is a parameter used for authentication. It helps in determining whether the client connecting to the server is authorized to connect to the server by sharing a common key. For a given server-key, you provide the hostname and the shared key. The host name has currently a very specific format. It must start with two __ and end with one _. This will probably be improved in the future.
moderator-check-on-whiteboard defines whether only the teacher or all people in the room have access to the whiteboard. This parameter is deprecated in videoconference 2.0.0. The value can be true or false. Any other strings different from true are considered false.
Video-streams-dir and vod-streams-dir are not used at all. See recorder config for more info.
3. Known issues and possible improvements
We are not living in a perfect world... Even if we make a lot of efforts to get an application flexible and easy to use, we still have a lot of
improvements to do. Here is a list of improvment to be done for configuration handling:
* Find a solution to get external config directory platform independant.
* Rename parameters video-streams-dir and vod-streams-dir to a more explicit name.
* Check whether hostname can be stripped of these underscores.
* Remove or integrate moderator-check-on-whiteboard.
* Add XML validation of the config file.

@ -72,7 +72,6 @@ class Agenda {
$id = Database::insert($this->tbl_personal_agenda, $attributes);
break;
case 'course':
//$attributes['user'] = api_get_user_id();
$attributes['title'] = $title;
$attributes['content'] = $content;
$attributes['start_date'] = $start;
@ -85,14 +84,14 @@ class Agenda {
$id = Database::insert($this->tbl_course_agenda, $attributes);
if ($id) {
//api_item_property_update($this->course, TOOL_CALENDAR_EVENT, $id, "AgendaAdded", api_get_user_id(), '','',$start, $end);
$group_id = api_get_group_id();
if ((!is_null($users_to_send)) or (!empty($group_id))) {
$send_to = self::separate_users_groups($users_to_send);
if (isset($send_to['everyone']) && $send_to['everyone']) {
api_item_property_update($this->course, TOOL_CALENDAR_EVENT, $id,"AgendaAdded", api_get_user_id(), '','',$start,$end);
api_item_property_update($this->course, TOOL_CALENDAR_EVENT, $id,"AgendaAdded", api_get_user_id(), $group_id ,'', $start, $end);
} else {
// storing the selected groups
if (is_array($send_to['groups'])) {
@ -103,8 +102,8 @@ class Agenda {
// storing the selected users
if (is_array($send_to['users'])) {
foreach ($send_to['users'] as $my_user_id) {
api_item_property_update($this->course, TOOL_CALENDAR_EVENT, $id, "AgendaAdded", api_get_user_id(), 0, $my_user_id, $start,$end);
foreach ($send_to['users'] as $to_user_id) {
api_item_property_update($this->course, TOOL_CALENDAR_EVENT, $id, "AgendaAdded", api_get_user_id(), $group_id, $to_user_id, $start, $end);
}
}
}
@ -114,7 +113,6 @@ class Agenda {
self::store_agenda_item_as_announcement($id);
}
}
break;
case 'admin':
$attributes['title'] = $title;
@ -261,7 +259,7 @@ class Agenda {
* @param int course id *integer* not the course code
*
*/
function get_events($start, $end, $user_id, $course_id = null, $group_id = null) {
function get_events($start, $end, $course_id = null, $group_id = null) {
switch ($this->type) {
case 'admin':
@ -424,6 +422,7 @@ class Agenda {
WHERE date >= '".$start."' AND (enddate <='".$end."' OR enddate IS NULL) AND user = $user_id";
$result = Database::query($sql);
$my_events = array();
if (Database::num_rows($result)) {
while ($row = Database::fetch_array($result, 'ASSOC')) {
$event = array();
@ -455,7 +454,6 @@ class Agenda {
function get_course_events($start, $end, $course_info, $group_id = 0) {
$course_id = $course_info['real_id'];
$group_list = GroupManager::get_group_list(null, $course_info['code']);
$group_name_list = array();
@ -709,7 +707,6 @@ class Agenda {
$html = '<select id="users_to_send_id" data-placeholder="'.get_lang('Select').'" name="users_to_send[]" multiple="multiple" style="width:250px" class="chzn-select">';
// adding the groups to the select form
if (isset($to_already_selected) && $to_already_selected==='everyone') {
}
@ -718,12 +715,13 @@ class Agenda {
if (is_array($group_list)) {
$html .= '<optgroup label="'.get_lang('Groups').'">';
foreach ($group_list as $this_group) {
//api_display_normal_message("group " . $thisGroup[id] . $thisGroup[name]);
if (!is_array($to_already_selected) || !in_array("GROUP:".$this_group['id'], $to_already_selected)) {
// $to_already_selected is the array containing the groups (and users) that are already selected
$html .= "<option value=\"GROUP:".$this_group['id']."\">".
$this_group['name']." &ndash; " . $this_group['userNb'] . " " . get_lang('Users') .
"</option>";
$count_users = isset($this_group['count_users']) ? $this_group['count_users'] : $this_group['userNb'];
$count_users = " &ndash; $count_users ".get_lang('Users');
$html .= '<option value="GROUP:'.$this_group['id'].'"> '.$this_group['name'].$count_users.'</option>';
//$html .= "<option value=\"GROUP:".$this_group['id']."\"> ".$this_group['name']." ".get_lang('Users')."</option>";
}
}
$html .= '</optgroup>';

@ -26,10 +26,10 @@ $action = isset($_GET['action']) ? $_GET['action'] : null;
$origin = isset($_GET['origin']) ? $_GET['origin'] : null;
$this_section = SECTION_COURSES;
require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
if (empty($action)) {
header('Location: agenda_js.php?type=course');
$url = api_get_path(WEB_CODE_PATH).'calendar/agenda_js.php?type=course';
header("Location: $url");
exit;
}

@ -37,19 +37,41 @@ if (api_is_platform_admin() && $type == 'admin') {
if (isset($_REQUEST['cidReq']) && !empty($_REQUEST['cidReq'])) {
$type = 'course';
}
$is_group_tutor = false;
$group_id = api_get_group_id();
if (!empty($group_id)) {
$is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
$group_properties = GroupManager :: get_group_properties($group_id);
$interbreadcrumb[] = array ("url" => "../group/group.php", "name" => get_lang('Groups'));
$interbreadcrumb[] = array ("url"=>"../group/group_space.php?gidReq=".$group_id, "name"=> get_lang('GroupSpace').' '.$group_properties['name']);
}
$tpl = new Template(get_lang('Agenda'));
$tpl->assign('use_google_calendar', 0);
$can_add_events = 0;
switch($type) {
case 'admin':
api_protect_admin_script();
$this_section = SECTION_PLATFORM_ADMIN;
if (api_is_platform_admin()) {
$can_add_events = 1;
}
break;
case 'course':
api_protect_course_script();
$this_section = SECTION_COURSES;
if (api_is_allowed_to_edit()) {
$can_add_events = 1;
}
if (!empty($group_id)) {
if ($is_group_tutor) {
$can_add_events = 1;
}
}
break;
case 'personal':
if (api_is_anonymous()) {
@ -61,20 +83,13 @@ switch($type) {
$tpl->assign('google_calendar_url', $extra_field_data['google_calendar_url']);
}
$this_section = SECTION_MYAGENDA;
break;
}
$can_add_events = 0;
if (api_is_platform_admin() && $type == 'admin') {
if (!api_is_anonymous()) {
$can_add_events = 1;
}
if (api_is_allowed_to_edit() && $type == 'course') {
$can_add_events = 1;
}
if (!api_is_anonymous() && $type == 'personal') {
$can_add_events = 1;
break;
}
//Setting translations
$day_short = api_get_week_days_short();
$days = api_get_week_days_long();
@ -108,8 +123,7 @@ $tpl->assign('region_value', $region_value);
$tpl->assign('export_ical_confidential_icon', Display::return_icon($export_icon_high, get_lang('ExportiCalConfidential')));
if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) && api_is_allowed_to_session_edit(false,true)) {
if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_edit_agenda') && !api_is_anonymous()) && api_is_allowed_to_session_edit(false,true) OR $is_group_tutor) {
if ($type == 'course') {
$actions = display_courseadmin_links();
}
@ -118,9 +132,15 @@ if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_ed
//Calendar Type : course, admin, personal
$tpl->assign('type', $type);
//Calendar type label
$tpl->assign('type_label', get_lang(ucfirst($type).'Calendar'));
$type_event_class = $type.'_event';
$type_label = get_lang(ucfirst($type).'Calendar');
if ($type == 'course' && !empty($group_id)) {
$type_event_class = 'group_event';
$type_label = get_lang('GroupCalendar');
}
$tpl->assign('type_label', $type_label);
$tpl->assign('type_event_class', $type_event_class);
//Current user can add event?
$tpl->assign('can_add_events', $can_add_events);
@ -131,15 +151,22 @@ $tpl->assign('web_agenda_ajax_url', $agenda_ajax_url);
$course_code = api_get_course_id();
if (api_is_allowed_to_edit() && $course_code != '-1' && $type == 'course') {
if ((api_is_allowed_to_edit() || $is_group_tutor) && $course_code != '-1' && $type == 'course') {
$order = 'lastname';
if (api_is_western_name_order) {
$order = 'firstname';
}
if (!empty($group_id)) {
$group_list = array($group_id => $group_properties);
$user_list = GroupManager::get_subscribed_users($group_id);
} else {
$user_list = CourseManager::get_user_list_from_course_code(api_get_course_id(), api_get_session_id(), null, $order);
$group_list = CourseManager::get_group_list_of_course(api_get_course_id(), api_get_session_id());
}
$agenda = new Agenda();
//This will fill the select called #users_to_send_id
$select = $agenda->construct_not_selected_select_form($group_list, $user_list);
$tpl->assign('visible_to', $select);
}

@ -57,6 +57,40 @@ label, input, button, select, textarea, p {
font-size: inherit;
}
.badge-group {
width: 200px;
position: relative;
}
.badge-group .badge {
float:left;
position:relative;
}
.badge-group > :first-child {
z-index: 1000;
}
.badge-group > :nth-child(2) {
z-index: 900;
}
.badge-group > :nth-child(3) {
z-index: 800;
}
.badge-group > :nth-child(4) {
z-index: 700;
}
.badge-group > :nth-child(5) {
z-index: 600;
}
.badge-group .badge:not(:first-child) {
margin-left: -13px;
padding-left: 15px;
}
/* button with image */
button.add, button.save, button.cancel, button.refresh, button.upload, button.search, button.login, button.plus, button.minus, button.next, button.back {
padding-left:30px;

@ -43,8 +43,7 @@ class FillBlanks extends Question
* function which redifines Question::createAnswersForm
* @param the formvalidator instance
*/
function createAnswersForm ($form)
{
function createAnswersForm ($form) {
$defaults = array();
if (!empty($this->id)) {
@ -79,27 +78,28 @@ class FillBlanks extends Question
// javascript
echo '<script type="text/javascript">
function FCKeditor_OnComplete( editorInstance )
{
function FCKeditor_OnComplete( editorInstance ) {
if (window.attachEvent) {
editorInstance.EditorDocument.attachEvent("onkeyup", updateBlanks) ;
} else {
editorInstance.EditorDocument.addEventListener("keyup",updateBlanks,true);
}
}
var firstTime = true;
function updateBlanks() {
if (firstTime) {
field = document.getElementById("answer");
var answer = field.value; }
else {
var answer = field.value;
} else {
var oEditor = FCKeditorAPI.GetInstance(\'answer\');
answer = oEditor.GetXHTML( true ) ;
}
var blanks = answer.match(/\[[^\]]*\]/g);
var fields = "<div class=\"control-group\"><label class=\"control-label\">'.get_lang('Weighting').'</label><div class=\"controls\"><table>";
if (blanks!=null) {
for (i=0 ; i<blanks.length ; i++){
if (document.getElementById("weighting["+i+"]"))

@ -105,7 +105,7 @@ if (isset($_GET['export_pdf']) && $_GET['export_pdf'] == 'category') {
$params['only_total_category'] = true;
$params['join_firstname_lastname'] = true;
$params['show_official_code'] = true;
$params['export_pdf'] = true;
if ($cat[0]->is_locked() == true || api_is_platform_admin()) {
Display :: set_header(null, false, false);
export_pdf_flatview($cat, $users, $alleval, $alllinks, $params);
@ -121,10 +121,13 @@ if (isset($_GET['exportpdf'])) {
$export_pdf_form = new DataForm(DataForm::TYPE_EXPORT_PDF, 'export_pdf_form', null, api_get_self().'?exportpdf=&offset='.intval($_GET['offset']).'&selectcat='.intval($_GET['selectcat']), '_blank', '');
if ($export_pdf_form->validate()) {
$params = array();
$params = $export_pdf_form->exportValues();
Display :: set_header(null, false, false);
$params['join_firstname_lastname'] = true;
$params['show_usercode'] = true;
$params['show_official_code'] = true;
$params['export_pdf'] = true;
$params['only_total_category'] = false;
export_pdf_flatview($cat, $users, $alleval, $alllinks, $params);
} else {
Display :: display_header(get_lang('ExportPDF'));
@ -137,7 +140,6 @@ if (isset ($_GET['print'])) {
exit;
}
if (!empty($_GET['export_report']) && $_GET['export_report'] == 'export_report') {
if (api_is_platform_admin() || api_is_course_admin() || api_is_course_coach()) {
$user_id = null;

@ -320,9 +320,8 @@ class GradebookTable extends SortableTable {
if (api_is_allowed_to_edit()) {
$main_weight = intval($main_cat[0]->get_weight());
if (intval($total_weight) == $main_weight) {
//$label = Display::return_icon('accept.png', get_lang('Ok'));
$label = null;
$total = Display::badge($total_weight.' / '.$main_weight, 'success');
$total = score_badges(array($total_weight.' / '.$main_weight, '100%'));
} else {
$label = Display::return_icon('warning.png', sprintf(get_lang('TotalWeightMustBeX'), $main_weight) );
$total = Display::badge($total_weight.' / '.$main_weight, 'warning');
@ -338,7 +337,7 @@ class GradebookTable extends SortableTable {
if (count($main_cat) > 1) {
$main_weight = intval($main_cat[0]->get_weight());
if (intval($total_categories_weight) == $main_weight) {
$total = Display::badge($total_categories_weight.' / '.$main_weight, 'success');
$total = score_badges(array($total_categories_weight.' / '.$main_weight, '100%'));
} else {
$total = Display::badge($total_categories_weight.' / '.$main_weight, 'warning');
}

@ -12,7 +12,6 @@
*/
class FlatViewDataGenerator
{
// Sorting types constants
const FVDG_SORT_LASTNAME = 1;
const FVDG_SORT_FIRSTNAME = 2;
@ -60,12 +59,20 @@ class FlatViewDataGenerator
if (isset($this->params['show_official_code']) && $this->params['show_official_code']) {
$headers[] = get_lang('OfficialCode');
}
if (isset($this->params['join_firstname_lastname']) && $this->params['join_firstname_lastname']) {
$headers[] = get_lang('Name');
if (api_is_western_name_order()) {
$headers[] = get_lang('FirstnameAndLastname');
} else {
$headers[] = get_lang('LastnameAndFirstname');
}
} else {
if (api_is_western_name_order()) {
$headers[] = get_lang('FirstName');
$headers[] = get_lang('LastName');
} else {
$headers[] = get_lang('LastName');
$headers[] = get_lang('FirstName');
}
}
if (!isset($items_count)) {
$items_count = count($this->evals_links) - $items_start;
@ -107,10 +114,14 @@ class FlatViewDataGenerator
foreach ($allcat as $sub_cat) {
$sub_cat_weight = 100*$sub_cat->get_weight()/$main_weight;
$headers[] = Display::url($sub_cat->get_name(), api_get_self().'?selectcat='.$sub_cat->get_id()).' '.$sub_cat_weight.' % ';
$add_weight = " $sub_cat_weight %";
if (isset($this->params['export_pdf']) && $this->params['export_pdf']) {
$add_weight = null;
}
$headers[] = Display::url($sub_cat->get_name(), api_get_self().'?selectcat='.$sub_cat->get_id()).$add_weight;
}
} else {
if (!isset($this->params['only_total_category'])) {
if (!isset($this->params['only_total_category']) || (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)) {
for ($count=0; ($count < $items_count ) && ($items_start + $count < count($this->evals_links)); $count++) {
$item = $this->evals_links[$count + $items_start];
$sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
@ -119,7 +130,7 @@ class FlatViewDataGenerator
}
}
}
$headers[] = get_lang('GradebookQualificationTotal').' 100%';
$headers[] = api_strtoupper(get_lang('GradebookQualificationTotal'));
return $headers;
}
@ -175,12 +186,14 @@ class FlatViewDataGenerator
if ($items_count < 0) {
$items_count = 0;
}
// copy users to a new array that we will sort
// TODO - needed ?
$usertable = array ();
foreach ($this->users as $user) {
$usertable[] = $user;
}
// sort users array
if ($users_sorting & self :: FVDG_SORT_LASTNAME) {
usort($usertable, array ('FlatViewDataGenerator','sort_by_last_name'));
@ -233,18 +246,51 @@ class FlatViewDataGenerator
$use_grade_model = false;
}
$export_to_pdf = false;
if (isset($this->params['export_pdf']) && $this->params['export_pdf']) {
$export_to_pdf = true;
}
foreach ($selected_users as $user) {
$row = array();
if ($export_to_pdf) {
$row['user_id'] = $user_id = $user[0]; //user id
} else {
$row[] = $user_id = $user[0]; //user id
}
if (isset($this->params['show_official_code']) && $this->params['show_official_code']) {
if ($export_to_pdf) {
$row['official_code'] = $user[4]; //official code
} else {
$row[] = $user[4]; //official code
}
}
if (isset($this->params['join_firstname_lastname']) && $this->params['join_firstname_lastname']) {
if ($export_to_pdf) {
$row['name'] = api_get_person_name($user[3], $user[2]); //last name
} else {
$row[] = api_get_person_name($user[3], $user[2]); //last name
}
} else {
if ($export_to_pdf) {
if (api_is_western_name_order()) {
$row['firstname'] = $user[3];
$row['lastname'] = $user[2];
} else {
$row['lastname'] = $user[2];
$row['firstname'] = $user[3];
}
} else {
if (api_is_western_name_order()) {
$row[] = $user[3]; //first name
$row[] = $user[2]; //last name
} else {
$row[] = $user[2]; //last name
$row[] = $user[3]; //first name
}
}
}
$item_value = 0;
@ -278,7 +324,7 @@ class FlatViewDataGenerator
//$temp_score = $scoredisplay->display_score($score, SCORE_DIV_PERCENT, SCORE_ONLY_SCORE);
$temp_score = $scoredisplay->display_score($score, SCORE_DIV_SIMPLE_WITH_CUSTOM);
if (!isset($this->params['only_total_category'])) {
if (!isset($this->params['only_total_category']) || (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)) {
if (!$show_all) {
$row[] = $temp_score.' ';
} else {
@ -309,17 +355,12 @@ class FlatViewDataGenerator
$item_value = $item_value*$item->get_weight();
$item_value = $main_weight*$item_value/$item->get_weight();
}
//if ($debug) var_dump($item_value);
$item_total += $item->get_weight();
//SCORE_DIV, SCORE_PERCENT, SCORE_DIV_PERCENT, SCORE_AVERAGE
$temp_score = $scoredisplay->display_score($score, SCORE_DIV_PERCENT, SCORE_ONLY_SCORE);
//$temp_score = $scoredisplay->display_score($score, SCORE_DIV_SIMPLE_WITH_CUSTOM);
if (!isset($this->params['only_total_category'])) {
if (!isset($this->params['only_total_category']) || (isset($this->params['only_total_category']) && $this->params['only_total_category'] == false)) {
if (!$show_all) {
//$row[] = $scoredisplay->display_score($score,SCORE_DIV_PERCENT);
if (in_array($item->get_type() , array(LINK_EXERCISE, LINK_DROPBOX, LINK_STUDENTPUBLICATION,
LINK_LEARNPATH, LINK_FORUM_THREAD, LINK_ATTENDANCE,LINK_SURVEY))) {
if (!empty($score[0])) {
@ -327,16 +368,11 @@ class FlatViewDataGenerator
} else {
$row[] = '';
}
//$row[] = $scoredisplay->display_score($score,SCORE_DIV_PERCENT, SCORE_ONLY_SCORE);
} else {
//$row[] = $scoredisplay->display_score($score,SCORE_DIV_PERCENT);
//$row[] = $score[0];
$row[] = $temp_score.' ';
}
} else {
//$row[] = $scoredisplay->display_score($score, SCORE_DECIMAL);
$row[] = $temp_score;
//$row[] = $scoredisplay->display_score($score, SCORE_DIV_PERCENT);
}
}
$item_value_total +=$item_value;
@ -348,11 +384,20 @@ class FlatViewDataGenerator
$total_score = array($item_value_total, $item_total);
if (!$show_all) {
if ($export_to_pdf) {
$row['total'] = $scoredisplay->display_score($total_score);
} else {
$row[] = $scoredisplay->display_score($total_score);
}
} else {
if ($export_to_pdf) {
$row['total'] = $scoredisplay->display_score($total_score, SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS);
} else {
$row[] = $scoredisplay->display_score($total_score, SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS);
}
}
unset($score);
//var_dump($row);exit;
$data[] = $row;
}
return $data;

@ -30,16 +30,6 @@ require_once api_get_path(LIBRARY_PATH).'grade_model.lib.php';
* @return boolean True on success, false on failure
*/
function add_resource_to_course_gradebook($category_id, $course_code, $resource_type, $resource_id, $resource_name='', $weight=0, $max=0, $resource_description='', $visible=0, $session_id = 0) {
/* See defines in lib/be/linkfactory.class.php
define('LINK_EXERCISE',1);
define('LINK_DROPBOX',2);
define('LINK_STUDENTPUBLICATION',3);
define('LINK_LEARNPATH',4);
define('LINK_FORUM_THREAD',5),
define('LINK_WORK',6);
*/
require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be.inc.php';
$link = LinkFactory :: create($resource_type);
$link->set_user_id(api_get_user_id());
$link->set_course_code($course_code);
@ -72,17 +62,11 @@ function add_resource_to_course_gradebook($category_id, $course_code, $resource_
}
function block_students() {
//if (!api_is_allowed_to_create_course()) {
if (!api_is_allowed_to_edit()) {
api_not_allowed();
}
}
/**
* Returns the info header for the user result page
* @param $userid
*/
/**
* Returns the course name from a given code
* @param string $code
@ -95,6 +79,7 @@ function get_course_name_from_code($code) {
return $col['title'];
}
}
/**
* Builds an img tag for a gradebook item
* @param string $type value returned by a gradebookitem's get_icon_name()
@ -157,7 +142,6 @@ function get_icon_file_name ($type) {
return api_get_path(WEB_IMG_PATH).$icon;
}
/**
* Builds the course or platform admin icons to edit a category
* @param object $cat category object
@ -211,11 +195,6 @@ function build_edit_icons_cat($cat, $selectcat) {
} else {
//$modify_icons .= '&nbsp;<img src="../img/deplacer_fichier_na.gif" border="0" title="' . get_lang('Move') . '" alt="" />';
}
if (empty($grade_model_id) || $grade_model_id == -1) {
/*$modify_icons .= ' <a href="gradebook_edit_all.php?id_session='.api_get_session_id().'&amp;cidReq='.$cat->get_course_code().'&selectcat=' . $cat->get_id() . '"> '.
Display::return_icon('percentage.png', get_lang('EditAllWeights'),'',ICON_SIZE_SMALL).' </a>'; */
}
if ($cat->is_locked() && !api_is_platform_admin()) {
$modify_icons .= Display::return_icon('delete_na.png', get_lang('DeleteAll'),'',ICON_SIZE_SMALL);
} else {
@ -372,7 +351,6 @@ function get_resource_from_course_gradebook($link_id) {
*/
function remove_resource_from_course_gradebook($link_id) {
if ( empty($link_id) ) { return false; }
require_once api_get_path(SYS_CODE_PATH).'gradebook/lib/be.inc.php';
// TODO find the corresponding category (the first one for this course, ordered by ID)
$l = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
$sql = "DELETE FROM $l WHERE id = ".(int)$link_id;
@ -410,7 +388,6 @@ function get_course_id_by_link_id($id_link) {
}
function get_table_type_course($type) {
global $_configuration;
global $table_evaluated;
return Database::get_course_table($table_evaluated[$type][0]);
}
@ -699,9 +676,11 @@ function load_gradebook_select_in_tool($form) {
}
}
/**
* PDF report creation
*/
function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array()) {
// Beginning of PDF report creation
//Getting data
$printable_data = get_printable_data($cat[0], $users, $alleval, $alllinks, $params);
// Reading report's CSS
@ -709,7 +688,6 @@ function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array(
$css = file_exists($css_file) ? @file_get_contents($css_file) : '';
// HTML report creation first
$time = time();
$course_code = trim($cat[0]->get_course_code());
$organization = api_get_setting('Institution');
@ -758,16 +736,19 @@ function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array(
if ($use_grade_model) {
if ($parent_id == 0) {
$title = '<h2 align="center">'.get_lang('FlatView').'</h2>';
$title = '<h2 align="center">'.api_strtoupper(get_lang('Average')).'<br />'.get_lang('Detailed').'</h2>';
} else {
$title = '<h2 align="center">'.$cat[0]->get_description().' - ('.$cat[0]->get_name().') </h2>';
$title = '<h2 align="center"> '.api_strtoupper(get_lang('Average')).'<br />'.$cat[0]->get_description().' - ('.$cat[0]->get_name().')</h2>';
}
} else {
$title = '<h2 align="center">'.get_lang('FlatView').'</h2>';
if ($parent_id == 0) {
$title = '<h2 align="center">'.api_strtoupper(get_lang('Average')).'<br />'.get_lang('Detailed').'</h2>';
} else {
$title = '<h2 align="center">'.api_strtoupper(get_lang('Average')).'</h2>';
}
}
Display::$global_template->assign('pdf_title', $title);
//Showing only the current teacher/admin instead the all teacherlist name see BT#4080
//$teacher_list = CourseManager::get_teacher_list_from_course_code_to_string($course_code);
$user_info = api_get_user_info();
@ -784,53 +765,49 @@ function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array(
$columns = count($printable_data[0]);
$has_data = is_array($printable_data[1]) && count($printable_data[1]) > 0;
if (api_is_western_name_order()) {
// Choosing the right person name order according to the current language.
$firstname_position = 0;
$lastname_position = 1;
if (!isset($params['join_firstname_lastname'])) {
if (isset($params['show_usercode']) && $params['show_usercode'] ) {
$firstname_position ++;
$lastname_position ++;
}
list($printable_data[0][$firstname_position], $printable_data[0][$lastname_position]) = array($printable_data[0][$lastname_position], $printable_data[0][$firstname_position]);
if ($has_data) {
foreach ($printable_data[1] as &$printable_data_row) {
list($printable_data_row[$firstname_position], $printable_data_row[$lastname_position]) = array($printable_data_row[$lastname_position], $printable_data_row[$firstname_position]);
}
}
}
}
$table = new HTML_Table(array('class' => 'data_table'));
$row = 0;
$column = 0;
$table->setHeaderContents($row, $column, '#');$column++;
$table->setHeaderContents($row, $column, get_lang('NumberAbbreviation'));
$column++;
foreach ($printable_data[0] as $printable_data_cell) {
$printable_data_cell = strip_tags($printable_data_cell);
$table->setHeaderContents($row, $column, $printable_data_cell);
$column++;
}
$row++;
if ($has_data) {
$counter = 1;
//var_dump($printable_data);exit;
foreach ($printable_data[1] as &$printable_data_row) {
$column = 0;
$table->setCellContents($row, $column, $counter);
$table->updateCellAttributes($row, $column, 'align="center"');
$column++; $counter++;
$column++;
$counter++;
foreach ($printable_data_row as $key => &$printable_data_cell) {
$attributes = array();
$attributes['align'] = 'center';
$attributes['style'] = null;
foreach ($printable_data_row as &$printable_data_cell) {
if ($key === 'name') {
$attributes['align'] = 'left';
}
if ($key === 'total') {
$attributes['style'] = 'font-weight:bold';
}
//var_dump($key, $printable_data_cell, $attributes);
$table->setCellContents($row, $column, $printable_data_cell);
$table->updateCellAttributes($row, $column, 'align="center"');
$table->updateCellAttributes($row, $column, $attributes);
$column++;
}
$table->updateRowAttributes($row, $row % 2 ? 'class="row_even"' : 'class="row_odd"', true);
$row++;
}
//exit;
} else {
$column = 0;
$table->setCellContents($row, $column, get_lang('NoResults'));
@ -854,11 +831,30 @@ function export_pdf_flatview($cat, $users, $alleval, $alllinks, $params = array(
$pdf = new PDF($page_format, $params['orientation']);
// Sending the created PDF report to the client
$file_name = date('YmdHi_', $time);
$file_name = null;
if (!empty($course_code)) {
$file_name .= $course_code.'_';
$file_name .= $course_code;
}
$file_name .= get_lang('FlatView').'.pdf';
$file_name = api_get_utc_datetime();
$file_name = get_lang('FlatView').'_'.$file_name;
$pdf->content_to_pdf($html, $css, $file_name, api_get_course_id());
exit;
}
function score_badges($list_values) {
$counter = 1;
$badges = array();
foreach ($list_values as $value) {
$class = 'info';
if ($counter == 1) {
$class = 'success';
}
$counter++;
$badges[] = Display::badge($value, $class);
}
return Display::badge_group($badges);
}

@ -25,16 +25,16 @@ api_protect_course_script(true);
/* Libraries & settings */
require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
$group_id = api_get_group_id();
/* Constants & variables */
$current_group = GroupManager :: get_group_properties(api_get_group_id());
$current_group = GroupManager :: get_group_properties($group_id);
/* Header */
$nameTools = get_lang('EditGroup');
$interbreadcrumb[] = array ('url' => 'group.php', 'name' => get_lang('Groups'));
$is_group_member = GroupManager :: is_tutor_of_group(api_get_user_id(), api_get_group_id());
$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);
@ -125,43 +125,8 @@ $form->add_textfield('name', get_lang('GroupName'));
// Description
$form->addElement('textarea', 'description', get_lang('Description'), array ('class' => 'span6', 'rows' => 6));
// Search Members of group
//$form = new FormValidator('search_member', 'get', 'group_edit', '', null, false);
//$renderer = & $form->defaultRenderer();
//$renderer->setElementTemplate('<span>{element}</span> ');
//$form->add_textfield('keyword', get_lang('GroupMembers'), false);
//$form->addElement('style_submit_button', 'submit', get_lang('Search'), 'class="search"');
// Getting all the users
/*
if (isset($_SESSION['id_session'])) {
$complete_user_list = CourseManager :: get_user_list_from_course_code($_course['id'], true, $_SESSION['id_session']);
$complete_user_list2 = CourseManager :: get_coach_list_from_course_code($_course['id'], $_SESSION['id_session']);
$complete_user_list = array_merge($complete_user_list, $complete_user_list2);
} else {
$complete_user_list = CourseManager :: get_user_list_from_course_code($_course['id']);
}
foreach ($complete_user_list as $user_id => $o_course_user) {
if ((isset ($_GET['keyword']) && search_members_keyword($o_course_user['firstname'], $o_course_user['lastname'], $o_course_user['username'], $o_course_user['official_code'], $_GET['keyword'])) || !isset($_GET['keyword']) || empty($_GET['keyword'])) {
$groups_name = GroupManager :: get_user_group_name($user_id);
if ($is_western_name_order) {
$temp[] = $o_course_user['firstname'];
$temp[] = $o_course_user['lastname'];
} else {
$temp[] = $o_course_user['lastname'];
$temp[] = $o_course_user['firstname'];
}
$temp[] = $o_course_user['role'];
$temp[] = implode(', ', $groups_name); //Group
$temp[] = $o_course_user['official_code'];
}
}*/
$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) {
@ -196,18 +161,19 @@ $group_tutors_element->setButtonAttributes('remove', array('class' => 'btn arrow
// Group members
$group_member_list = GroupManager :: get_subscribed_users($current_group['id']);
$selected_users = array ();
foreach ($group_member_list as $index => $user) {
//$possible_users[$user['user_id']] = api_get_person_name($user['firstname'], $user['lastname']);
$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) )
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;"');

@ -20,19 +20,22 @@ $current_course_tool = TOOL_GROUP;
// Notice for unauthorized people.
api_protect_course_script(true);
/* Libraries & config files */
require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php';
require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
require_once api_get_path(SYS_CODE_PATH).'forum/forumconfig.inc.php';
/* MAIN CODE */
$current_group = GroupManager :: get_group_properties($_SESSION['_gid']);
if (!is_array($current_group) ) {
//display some error message
$group_id = api_get_group_id();
$user_id = api_get_user_id();
$current_group = GroupManager :: get_group_properties($group_id);
if (empty($current_group)) {
api_not_allowed();
}
$this_section = SECTION_COURSES;
$nameTools = get_lang('GroupSpace');
$interbreadcrumb[] = array ('url' => 'group.php', 'name' => get_lang('Groups'));
@ -69,16 +72,16 @@ Display::display_introduction_section(TOOL_GROUP);
/*
* User wants to register in this group
*/
if (!empty($_GET['selfReg']) && GroupManager :: is_self_registration_allowed($_SESSION['_user']['user_id'], $current_group['id'])) {
GroupManager :: subscribe_users($_SESSION['_user']['user_id'], $current_group['id']);
if (!empty($_GET['selfReg']) && GroupManager :: is_self_registration_allowed($user_id, $current_group['id'])) {
GroupManager :: subscribe_users($user_id, $current_group['id']);
Display :: display_normal_message(get_lang('GroupNowMember'));
}
/*
* User wants to unregister from this group
*/
if (!empty($_GET['selfUnReg']) && GroupManager :: is_self_unregistration_allowed($_SESSION['_user']['user_id'], $current_group['id'])) {
GroupManager :: unsubscribe_users($_SESSION['_user']['user_id'], $current_group['id']);
if (!empty($_GET['selfUnReg']) && GroupManager :: is_self_unregistration_allowed($user_id, $current_group['id'])) {
GroupManager :: unsubscribe_users($user_id, $current_group['id']);
Display::display_normal_message(get_lang('StudentDeletesHimself'));
}
echo '<div class="actions">';
@ -88,7 +91,7 @@ echo '<a href="group.php">'.Display::return_icon('back.png',get_lang('BackToGrou
* Register to group
*/
$subscribe_group = '';
if (GroupManager :: is_self_registration_allowed($_SESSION['_user']['user_id'], $current_group['id'])) {
if (GroupManager :: is_self_registration_allowed($user_id, $current_group['id'])) {
$subscribe_group = '<a class="btn" href="'.api_get_self().'?selfReg=1&amp;group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.get_lang("RegIntoGroup").'</a>';
}
@ -96,7 +99,7 @@ if (GroupManager :: is_self_registration_allowed($_SESSION['_user']['user_id'],
* Unregister from group
*/
$unsubscribe_group = '';
if (GroupManager :: is_self_unregistration_allowed($_SESSION['_user']['user_id'], $current_group['id'])) {
if (GroupManager :: is_self_unregistration_allowed($user_id, $current_group['id'])) {
$unsubscribe_group = '<a class="btn" href="'.api_get_self().'?selfUnReg=1" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"),ENT_QUOTES))."'".')) return false;">'.get_lang("StudentUnsubscribe").'</a>';
}
echo '&nbsp;</div>';
@ -114,10 +117,6 @@ if (isset($_GET['action'])) {
$course_code = $_course['sysCode'];
$is_course_member = CourseManager :: is_user_subscribed_in_real_or_linked_course(api_get_user_id(), $course_code);
/*
* Group title and comment
*/
/*
* Edit the group
*/
@ -242,6 +241,7 @@ echo '</ul>';
* List all the tutors of the current group
*/
$tutors = GroupManager::get_subscribed_tutors($current_group['id']);
$tutor_info = '';
if (count($tutors) == 0) {
$tutor_info = get_lang('GroupNoneMasc');
@ -361,23 +361,22 @@ function get_group_user_data($from, $number_of_items, $column, $direction) {
$sql .= " LIMIT $from,$number_of_items";
} else {
if (api_is_allowed_to_edit()) {
$sql = "SELECT
user.user_id AS col0,
$sql = "SELECT DISTINCT
u.user_id AS col0,
".(api_is_western_name_order() ?
"user.firstname AS col1,
user.lastname AS col2,"
"u.firstname AS col1,
u.lastname AS col2,"
:
"user.lastname AS col1,
user.firstname AS col2,"
"u.lastname AS col1,
u.firstname AS col2,"
)."
user.email AS col3
FROM ".$table_user." user, ".$table_group_user." group_rel_user
WHERE group_rel_user.c_id = $course_id AND group_rel_user.user_id = user.user_id
AND group_rel_user.group_id = '".Database::escape_string($current_group['id'])."'";
u.email AS col3
FROM ".$table_user." u INNER JOIN ".$table_group_user." gu ON (gu.user_id = u.user_id) AND gu.c_id = $course_id
WHERE gu.group_id = '".Database::escape_string($current_group['id'])."'";
$sql .= " ORDER BY col$column $direction ";
$sql .= " LIMIT $from,$number_of_items";
} else {
$sql = "SELECT
$sql = "SELECT DISTINCT
user.user_id AS col0,
". (api_is_western_name_order() ?
"user.firstname AS col1,

@ -14,17 +14,19 @@ $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
$type = isset($_REQUEST['type']) && in_array($_REQUEST['type'], array('personal', 'course', 'admin')) ? $_REQUEST['type'] : 'personal';
if ($type =='course') {
// Access control
api_protect_course_script(true);
}
$agenda = new Agenda();
$group_id = api_get_group_id();
$is_group_tutor = GroupManager::is_tutor_of_group(api_get_user_id(), $group_id);
$agenda = new Agenda();
$agenda->type = $type; //course,admin or personal
switch ($action) {
case 'add_event':
if (!api_is_allowed_to_edit(null, true) && $type == 'course') {
if ((!api_is_allowed_to_edit(null, true) && !$is_group_tutor) && $type == 'course') {
break;
}
echo $agenda->add_event($_REQUEST['start'], $_REQUEST['end'], $_REQUEST['all_day'], $_REQUEST['view'],
@ -69,7 +71,7 @@ switch ($action) {
case 'get_events':
$start = $_REQUEST['start'];
$end = $_REQUEST['end'];
$events = $agenda->get_events($start, $end, api_get_user_id(), api_get_course_int_id());
$events = $agenda->get_events($start, $end, api_get_course_int_id(), $group_id);
echo $events;
break;
case 'get_user_agenda':

@ -1410,6 +1410,15 @@ class Display {
return null;
}
function badge_group($badge_list) {
$html = '<div class="badge-group">';
foreach ($badge_list as $badge) {
$html .= $badge;
}
$html .= '</div>';
return $html;
}
function label($content, $type = null) {
$class = '';
switch ($type) {

@ -157,8 +157,8 @@ class GradeModel extends Model {
return null;
}
public function save($params) {
$id = parent::save($params);
public function save($params, $show_query = false) {
$id = parent::save($params, $show_query);
if (!empty($id)) {
foreach ($params['components'] as $component) {
if (!empty($component['title']) && !empty($component['percentage']) && !empty($component['acronym'])) {
@ -203,8 +203,8 @@ class GradeModelComponents extends Model {
$this->table = Database::get_main_table(TABLE_GRADE_MODEL_COMPONENTS);
}
public function save($params) {
$id = parent::save($params);
public function save($params, $show_query = false) {
$id = parent::save($params, $show_query);
return $id;
}
}

@ -435,11 +435,13 @@ class GroupManager {
if (empty($group_id) or !is_integer(intval($group_id)) ) {
return null;
}
$result = array();
$table_group = Database :: get_course_table(TABLE_GROUP);
$sql = "SELECT * FROM $table_group WHERE c_id = $course_id AND id = ".Database::escape_string($group_id);
$sql = "SELECT * FROM $table_group WHERE c_id = $course_id AND id = ".intval($group_id);
$db_result = Database::query($sql);
$db_object = Database::fetch_object($db_result);
$result['id'] = $db_object->id;
$result['name'] = $db_object->name;
$result['tutor_id'] = isset($db_object->tutor_id)?$db_object->tutor_id:null;
@ -456,6 +458,10 @@ class GroupManager {
$result['self_registration_allowed'] = $db_object->self_registration_allowed;
$result['self_unregistration_allowed'] = $db_object->self_unregistration_allowed;
$result['count_users'] = count(self::get_subscribed_users($group_id));
$result['count_tutor'] = count(self::get_subscribed_tutors($group_id));
$result['count_all'] = $result['count_users'] + $result['count_tutor'];
return $result;
}
/**
@ -745,7 +751,7 @@ class GroupManager {
* @param int $group_id The group
* @return array list of user id
*/
public static function get_users ($group_id) {
public static function get_users ($group_id, $load_extra_info = false) {
$group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
$group_id = Database::escape_string($group_id);
$course_id = api_get_course_int_id();
@ -753,11 +759,36 @@ class GroupManager {
$res = Database::query($sql);
$users = array ();
while ($obj = Database::fetch_object($res)) {
if ($load_extra_info) {
$users[] = api_get_user_info($obj->user_id);
} else {
$users[] = $obj->user_id;
}
}
return $users;
}
public function get_members_and_tutors($group_id) {
$group_user_table = Database :: get_course_table(TABLE_GROUP_USER);
$tutor_user_table = Database :: get_course_table(TABLE_GROUP_TUTOR);
$course_id = api_get_course_int_id();
$group_id = intval($group_id);
$sql = "SELECT user_id FROM $group_user_table WHERE c_id = $course_id AND group_id = $group_id";
$res = Database::query($sql);
$users = array();
while ($obj = Database::fetch_object($res)) {
$users[] = api_get_user_info($obj->user_id);
}
$sql = "SELECT user_id FROM $tutor_user_table WHERE c_id = $course_id AND group_id = $group_id";
$res = Database::query($sql);
while ($obj = Database::fetch_object($res)) {
$users[] = api_get_user_info($obj->user_id);
}
return $users;
}
/**
* Returns users belonging to any of the group
@ -765,10 +796,8 @@ class GroupManager {
* @param array $groups list of group ids
* @return array list of user ids
*/
public static function get_groups_users($groups = array())
{
public static function get_groups_users($groups = array()) {
$result = array();
$tbl_group_user = Database::get_course_table(TABLE_GROUP_USER);
$course_id = api_get_course_int_id();
@ -778,8 +807,7 @@ class GroupManager {
FROM $tbl_group_user gu
WHERE c_id = $course_id AND gu.group_id IN ($groups)";
$rs = Database::query($sql);
while ($row = Database::fetch_array($rs))
{
while ($row = Database::fetch_array($rs)) {
$result[] = $row['user_id'];
}
@ -1083,7 +1111,7 @@ class GroupManager {
$member['lastname'] = $user->lastname;
$member['email'] = $user->email;
$member['username'] = $user->username;
$users[] = $member;
$users[$member['user_id']] = $member;
}
return $users;
}

@ -1134,7 +1134,6 @@ function api_get_anonymous_id() {
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
$row = Database::fetch_array($res);
//error_log('api_get_anonymous_id() returns '.$row['user_id'], 0);
return $row['user_id'];
}
// No anonymous user was found.
@ -2821,7 +2820,6 @@ function api_item_property_update($_course, $tool, $item_id, $lastedit_type, $us
$session_id = api_get_session_id();
}
// Definition of tables.
$TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
@ -5743,6 +5741,7 @@ function api_resource_is_locked_by_gradebook($item_id, $link_type, $course_code
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
$item_id = intval($item_id);
$link_type = intval($link_type);
$course_code = Database::escape_string($course_code);
$sql = "SELECT locked FROM $table WHERE locked = 1 AND ref_id = $item_id AND type = $link_type AND course_code = '$course_code' ";
$result = Database::query($sql);
if (Database::num_rows($result)) {

@ -1,10 +1,8 @@
<?php
/**
* Install database. Provides access to the Database class and allows to add hooks
* for logging, testing, etc during installation.
*
*
* Install database. Provides access to the Database class and allows to add
* hooks for logging, testing, etc during installation.
*
* @license see /license.txt
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva

@ -2,7 +2,7 @@
/*
for more information: see languages.txt in the lang folder.
*/
$CasMainActivateComment = "Enabling CAS authentication will allow users to authenticate with their CAS credentials";
$CasMainActivateComment = "Enabling CAS authentication will allow users to authenticate with their CAS credentials.<br/>Go to <a href='settings.php?category=CAS'>Plugin</a> to add a configurable 'CAS Login' button for your Chamilo campus.";
$AdminBy = "Administration by";
$AdministrationTools = "Administration";
$State = "Portal status";
@ -1540,4 +1540,12 @@ $GradebookDefaultWeightTitle = "Default weight in Gradebook";
$GradebookDefaultWeightComment = "This weight will be use in all courses by default";
$TeachersCanChangeScoreSettingsTitle = "Teachers can change the Gradebook score settings";
$TeachersCanChangeScoreSettingsComment = "When editing the Gradebook settings";
$GradebookEnableLockingTitle = "Enable locking of assessments by teachers";
$GradebookEnableLockingComment = "Once enabled, this option will enable locking of any assessment by the teachers of the corresponding course. This, in turn, will prevent any modification of results by the teacher inside the resources used in the assessment: exams, learning paths, tasks, etc. The only role authorized to unlock a locked assessment is the administrator. The teacher will be informed of this possibility. The locking and unlocking of gradebooks will be registered in the system's report of important activities";
$LdapDescriptionComment = "<div class='normal-message'> <br /><ul><li>LDAP authentication : <br />See I. below to configure LDAP <br />See II. below to activate LDAP authentication </li><br /><br /><li> Update user attributes, with LDAP data, after CAS authentication(see <a href='settings.php?category=CAS'>CAS configuration </a>) : <br />See I. below to configure LDAP <br />CAS manage user authentication, LDAP activation isn't required. </li><br /></ul></div><br /><h4>I. LDAP configuration</h4><h5>Edit file main/auth/external_login/ldap.conf.php </h5>-&gt; Edit values of array <code>&#36;extldap_config</code> <br /><br />Parameters are <br /><ul><li>base domain string (ex : 'base_dn' =&gt; 'DC=cblue,DC=be') </li><li>admin distinguished name (ex : 'admin_dn' =&gt;'CN=admin,dc=cblue,dc=be') </li><li>admin password (ex : 'admin_password' =&gt; '123456') </li><li>ldap host (ex : 'host' =&gt; array('1.2.3.4', '2.3.4.5', '3.4.5.6')) </li><li>filter (ex : 'filter' =&gt; '') </li><li>port (ex : 'port' =&gt; 389) </li><li>protocol version (2 or 3) (ex : 'protocol_version' =&gt; 3) </li><li>user_search (ex : 'user_search' =&gt; 'sAMAccountName=%username%') </li><li>encoding (ex : 'encoding' =&gt; 'UTF-8') </li><li>update_userinfo (ex : 'update_userinfo' =&gt; true) </li></ul>-&gt; To update correspondences between user and LDAP attributes, edit array <code>&#36;extldap_user_correspondance</code> <br />Array values are &lt;chamilo_field&gt; =&gt; &gt;ldap_field&gt; <br />Array structure is explained in file main/auth/external_login/ldap.conf.php<br /><br /><br /><h4>II. Activate LDAP authentication </h4><h5>Edit file main/inc/conf/configuration.php </h5>-&gt; Uncomment lines <br />&#36;extAuthSource[&quot;extldap&quot;][&quot;login&quot;] =&#36;_configuration['root_sys'].&#36;_configuration['code_append'].&quot;auth/external_login/login.ldap.php&quot;;<br />&#36;extAuthSource[&quot;extldap&quot;][&quot;newUser&quot;] =&#36;_configuration['root_sys'].&#36;_configuration['code_append'].&quot;auth/external_login/newUser.ldap.php&quot;;<br /><br />N.B. : LDAP users use same fields than platform users to login. <br />N.B. : LDAP activation adds a menu External authentication [LDAP] in &quot;add or modify&quot; user pages.";
$ShibbolethMainActivateTitle = "<h3>Shibboleth authentication</h3>";
$ShibbolethMainActivateComment = "<p>First of all, you have to configure Shibboleth for your web server.</p>To configure it for Chamilo<h5>edit file main/auth/shibboleth/config/aai.class.php</h5><p>Modify object &#36;result values with the name of your Shibboleth attributes</p><ul><li>&#36;result-&gt;unique_id = 'mail';</li><li>&#36;result-&gt;firstname = 'cn';</li><li>&#36;result-&gt;lastname = 'uid';</li><li>&#36;result-&gt;email = 'mail';</li><li>&#36;result-&gt;language = '-';</li><li>&#36;result-&gt;gender = '-';</li><li>&#36;result-&gt;address = '-';</li><li>&#36;result-&gt;staff_category = '-';</li><li>&#36;result-&gt;home_organization_type = '-'; </li><li>&#36;result-&gt;home_organization = '-';</li><li>&#36;result-&gt;affiliation = '-';</li><li>&#36;result-&gt;persistent_id = '-';</li><li>...</li></ul><br/>Go to <a href='settings.php?category=Shibboleth'>Plugin</a> to add a configurable 'Shibboleth Login' button for your Chamilo campus.";
$LdapDescriptionTitle = "<h3>LDAP autentication</h3>";
$FacebookMainActivateTitle = "<h3>Facebook authentication</h3>";
$FacebookMainActivateComment = "<p>First of all, you have create a Facebook Application (see <a href='https://developers.facebook.com/apps'>https://developers.facebook.com/apps</a>) with your Facebook account. In the Facebook Apps parameters, the site URL value should have a GET parameter 'action=fbconnect' (e.g. http://mychamilo.com/?action=fbconnect).</p>Then, <h5>edit file main/auth/external_login/facebook.conf.php</h5>and enter 'appId' and 'secret' values for &#36;facebook_config.<br/>Go to <a href='settings.php?category=Facebook'>Plugin</a> to add a configurable 'Facebook Login' button for your Chamilo campus.";
?>

@ -232,4 +232,5 @@ $SelectGradeModel = "Select a calification model";
$AllMustWeight100 = "The sum of all values must be 100";
$Components = "Components";
$OnlyActiveWhenThereAreAnyComponents = "This option is enabled if you have any evaluations or categories";
$GradebookLockedAlert = "This assessment has been locked. You cannot unlock it. If you really need to unlock it, please contact the platform administrator, explaining the reason why you would need to do that (it might otherwise be considered as fraud attempt).";
?>

@ -1220,4 +1220,14 @@ $Reload = "Reload";
$TimeSpentLastXDays = "Time spent the last %s days";
$TimeSpentBetweenXAndY = "Time spent between %s and %s";
$GoToCourse = "Go to the course";
$SubTotal = "Subtotal";
$Configure = "Configure";
$Regions = "Regions";
$CourseList = "Course list";
$NumberAbbreviation = "N°";
$FirstnameAndLastname = "First Name and Last Name";
$LastnameAndFirstname = "Last Name and First Name";
$Plugins = "Plugins";
$Detailed = "Detailed";
$ResourceLockedByGradebook = "This option is not available because this activity is contained by an assessment, which is currently locked. To unlock the assessment, ask your platform administrator.";
?>

@ -2,7 +2,7 @@
/*
for more information: see languages.txt in the lang folder.
*/
$CasMainActivateComment = "Activer l'authentification CAS permettra aux utilisateurs de s'identifier à l'aide de leur compte CAS";
$CasMainActivateComment = "Activer l'authentification CAS permettra aux utilisateurs de s'identifier à l'aide de leur compte CAS<br/>Vous trouverez dans les <a href='settings.php?category=CAS'>Plugin</a> un bouton 'Login CAS', parametrable, qui s'ajoutera sur la page d'accueil de votre campus Chamilo.";
$AdminBy = "Administration par";
$AdministrationTools = "Administration";
$State = "Etat du système";
@ -1506,4 +1506,9 @@ $CasUserAddLastnameAttributeComment = "Enregistrer le nom de famille CAS de l'ut
$ShowAdminToolbarTitle = "Afficher la barre d'administration";
$ShowAdminToolbarComment = "Affiche une barre d'outils globale au sommet de la page aux utilisateurs des rôles désignés. Cette barre d'outils, très similaire à celles de Wordpress et de Google, peut considérablement accélérer certaines opérations complexes et augmente l'espace disponible pour les contenus de cours, mais elle pourrait rendre certains utilisateurs confus.";
$FirstLetterCourseTitle = "Première lettre (title)";
$LdapDescriptionComment = "<div class='normal-message'> <br /><ul><li>Authentification LDAP : <br />Voir I. ci-dessous pour configurer LDAP <br />Voir II. ci-dessous pour activer l'authentification LDAP </li><br /><br /><li> Mise à jour des attributs de l'utilisateur, auprès du serveur LDAP,après une authentification CAS (voir <a href='settings.php?category=CAS'>configurationde CAS </a>) : <br />Voir I. ci-dessous pour configurer LDAP <br />L'authentification est gérée par CAS, il n'est pas nécessaired'activer l'authentification LDAP dans ce cas. </li><br /></ul></div><br /><h4>I. Configuration des paramètres du serveur LDAP </h4><h5>Éditez le fichier main/auth/external_login/ldap.conf.php </h5>-&gt; Mettez à jour les informations de configuration LDAP du tableau <code>&#36;extldap_config</code> <br /> Les paramètres sont <br /><ul><li>base domain string (ex : 'base_dn' =&gt; 'DC=cblue,DC=be') </li><li>admin distinguished name (ex : 'admin_dn' =&gt;'CN=admin,dc=cblue,dc=be') </li><li>admin password (ex : 'admin_password' =&gt; '123456') </li><li>ldap host (ex : 'host' =&gt; array('1.2.3.4', '2.3.4.5', '3.4.5.6')) </li><li>filter (ex : 'filter' =&gt; '') </li><li>port (ex : 'port' =&gt; 389) </li><li>protocol version (2 or 3) (ex : 'protocol_version' =&gt;3) </li><li>user_search (ex : 'user_search' =&gt; 'sAMAccountName=%username%') </li><li>encoding (ex : 'encoding' =&gt; 'UTF-8') </li><li>update_userinfo (ex : 'update_userinfo' =&gt; true) </li></ul>-&gt; Mettez à jour les informations de correspondances entre les attributsLDAP et les champs utilisateurs Chamilo du tableau <code>&#36;extldap_user_correspondance</code> <br /> Le tableau est de la forme : &lt;chamilo_field&gt; =&gt;&gt;ldap_field&gt; <br />Sa structure est détaillée dans le fichiermain/auth/external_login/ldap.conf.php <br /><br /><br /><h4>II. Activation de l'authentification LDAP </h4><h5>Éditez le fichier main/inc/conf/configuration.php </h5>-&gt; Décommenter les lignes <br />&#36;extAuthSource[&quot;extldap&quot;][&quot;login&quot;] =&#36;_configuration['root_sys'].&#36;_configuration['code_append'].&quot;auth/external_login/login.ldap.php&quot;;<br />&#36;extAuthSource[&quot;extldap&quot;][&quot;newUser&quot;] =&#36;_configuration['root_sys'].&#36;_configuration['code_append'].&quot;auth/external_login/newUser.ldap.php&quot;;<br /><br />Notes : les utilisateurs authentifiés par LDAP saisissent leur login et motde passe dans les même champs que les utilisateurs locaux à la plate forme.<br />Notes : activer l'authentification LDAP ajoute un menu Externalauthentification [LDAP] dans l'interface d'ajout et de modification d'unutilisateur.";
$ShibbolethMainActivateTitle = "<h3>Configuration de l'authentification Shibboleth</h3>";
$ShibbolethMainActivateComment = "<p>Vous devez, en premier lieu, configurer Shibboleth pour votre serveur web. Pour le configurer pour Chamilo.</p><h5>éditez le fichier main/auth/shibboleth/config/aai.class.php</h5><p>Modifiez les valeurs de l'objet &#36;result avec les nom des attributs retourné par votre serveur Shibboleth.</p>Les valeurs à modifier sont<ul><li>&#36;result-&gt;unique_id = 'mail';</li><li>&#36;result-&gt;firstname = 'cn';</li><li>&#36;result-&gt;lastname = 'uid';</li><li>&#36;result-&gt;email = 'mail';</li><li>&#36;result-&gt;language = '-';</li><li>&#36;result-&gt;gender = '-';</li><li>&#36;result-&gt;address = '-';</li><li>&#36;result-&gt;staff_category = '-';</li><li>&#36;result-&gt;home_organization_type = '-'; </li><li>&#36;result-&gt;home_organization = '-';</li><li>&#36;result-&gt;affiliation = '-';</li><li>&#36;result-&gt;persistent_id = '-';</li><li>...</li></ul><br/>Vous trouverez dans les <a href='settings.php?category=Shibboleth'>Plugin</a> un bouton 'Login Shibboleth', parametrable, qui s'ajoutera sur la page d'accueil de votre campus Chamilo.";
$FacebookMainActivateTitle = "<h3>Configuration de l'authentification via Facebook</h3>";
$FacebookMainActivateComment = "<p>Vous devez, en premier lieu, créer une application Facebook (cf. <a href='https://developers.facebook.com/apps'>https://developers.facebook.com/apps</a>) avec votre compte Facebbok. Le paramètre de l'application Facebook 'URL du site' doit comporter 'action=fbconnect' comme paramètre en GET (exemple : http://mychamilo.com/?action=fbconnect)</p>Ensuite, <h5>éditez le fichier main/auth/external_login/facebook.conf.php</h5>et entrez les valeurs 'appId' et 'secret', fournies par Facebbok, pour la variable &#36;facebook_config.<br/>Vous trouverez dans les <a href='settings.php?category=Facebook'>Plugin</a> un bouton 'Login Facebook', parametrable, qui s'ajoutera à la page d'accueil de votre campus Chamilo.";
?>

@ -179,7 +179,7 @@ $Statistics = "Statistika";
$langGrouplist = "Seznam skupin";
$langPrevious = "prejšnji";
$DestDirectoryDoesntExist = "Ciljna mapa ne obstaja";
$Courses = "tečaji";
$Courses = "Tečaji";
$In = "v";
$langShowAll = "Prikaži vse";
$langPage = "Stran";

@ -68,7 +68,7 @@ $ContactsGroups = "Kontakti skupine";
$ErrorSendingMessage = "Napaka pri poskusu pošiljanja sporočila.";
$PendingInvitations = "Čakajoča povabila";
$MyInbox = "Moja prihajajoča sporočila";
$ViewSharedProfile = "Skupen profil";
$ViewSharedProfile = "Javen profil";
$SeeAll = "Poglej vse";
$ImagesUploaded = "Naložene slike";
$ExtraInformation = "Dodatne informacije";
@ -80,7 +80,7 @@ $SocialAddToFriends = "Dodaj k mojim kontaktom";
$UserNonRegisteredAtTheCourse = "Uporabnik ni vpisan v tečaj";
$ChangeContactGroup = "Spremeni skupino kontaktov";
$Friend = "Prijatelj";
$ViewMySharedProfile = "Moj skupen profil";
$ViewMySharedProfile = "Moj javen profil";
$UserStatistics = "Poročila o tem uporabniku";
$EditUser = "Uredi tega uporabnika";
$ViewUser = "Poglej tega uporabnika";

@ -1541,4 +1541,8 @@ $AllowHRSkillsManagementTitle = "Permitir al perfil RRHH administrar las compete
$AllowHRSkillsManagementComment = "El usuario podrá crear, editar competencias";
$GradebookDefaultWeightTitle = "Peso total por defecto en la herramienta \"Evaluaciones\"";
$GradebookDefaultWeightComment = "Este peso será utilizado en todos los cursos";
$TeachersCanChangeScoreSettingsTitle = "Los profesores pueden cambiar la configuración de puntuación de las Evaluaciones";
$TeachersCanChangeScoreSettingsComment = "Al editar la configuración de las Evaluaciones";
$GradebookEnableLockingTitle = "Activar bloqueo de Evaluaciones por los profesores";
$GradebookEnableLockingComment = "Una vez activada, esta opción permitirá a los profesores bloquear cualquier evaluación dentro de su curso. Esto prohibirá al profesor cualquier modificación posterior de los resultados de sus alumnos en los recursos usados para esta evaluación: exámenes, lecciones, tareas, etc. El único rol autorizado a desbloquear una evaluación es el administrador. El profesor estará informado de esta posibilidad al intentar desbloquear la evaluación. El bloqueo como el desbloqueo estarán guardados en el registro de actividades importantes del sistema.";
?>

@ -104,7 +104,7 @@ $NumberOfPostsForThisUser = "Número de mensajes del usuario";
$AveragePostPerUser = "Promedio de mensajes por usuario";
$QualificationChangesHistory = "Historial de cambios en las calificaciones";
$MoreRecent = "mas reciente";
$Older = "mas antiguio";
$Older = "mas antiguo";
$OrderBy = "Ordenar por";
$WhoChanged = "Quien hizo el cambio";
$NoteChanged = "Nota cambiada";

@ -80,7 +80,7 @@ $LinkDeleted = "El componente de evaluación ha sido eliminado";
$EditEvaluation = "Modificar componente de evaluación";
$DeleteResult = "Eliminar resultados";
$Display = "Nivel";
$Average = "Media";
$Average = "Promedio";
$ViewStatistics = "Ver estadísticas";
$ResultAdded = "Resultado añadido";
$EvaluationStatistics = "Estadísticas de evaluación";
@ -103,9 +103,9 @@ $OverMax = "El valor que ha intentado guardar es superior al límite máximo est
$MoreInfo = "Más información";
$ResultsPerUser = "Resultados por usuario";
$TotalUser = "Total por usuario";
$AverageTotal = "Media total";
$AverageTotal = "Promedio total";
$Evaluation = "Componente de evaluación";
$EvaluationAverage = "Media de la evaluación";
$EvaluationAverage = "Promedio de la evaluación";
$EditCategory = "Editar sus propiedades";
$EditAllWeights = "Editar ponderaciones";
$GradebookQualificationTotal = "Total";
@ -133,7 +133,7 @@ $NoResultsAvailable = "No hay resultados disponibles";
$CannotChangeTheMaxNote = "No se puede cambiar la nota máxima";
$GradebookWeightUpdated = "Peso(s) modificado(s) correctamente";
$ChooseItem = "Seleccione un item";
$AverageResultsVsResource = "Media de resultados por componente de evaluación";
$AverageResultsVsResource = "Promedio de resultados por componente de evaluación";
$ToViewGraphScoreRuleMustBeEnabled = "Para ver el gráfico las reglas de puntuación deben haberse definido";
$GradebookPreviousWeight = "Ponderación previa";
$AddAssessment = "Crear";
@ -232,4 +232,5 @@ $SelectGradeModel = "Seleccionar un modelo de calificación";
$AllMustWeight100 = "La suma debe ser de 100";
$Components = "Componentes";
$OnlyActiveWhenThereAreAnyComponents = "Esta opción está habilitada si tiene evaluaciones o categorías";
$GradebookLockedAlert = "Esta evaluación ha sido bloqueada y no puede ser desbloqueada. Si necesita realmente desbloquearla, por favor contacte el administrador de la plataforma, explicando su razón (sino podría ser considerado como un intento de fraude).";
?>

@ -1225,4 +1225,14 @@ $Reload = "Recargar";
$TimeSpentLastXDays = "Tiempo dedicado en los últimos %s días";
$TimeSpentBetweenXAndY = "Tiempo dedicado entre el %s y el %s";
$GoToCourse = "Ir al curso";
$SubTotal = "Total parcial";
$Configure = "Configurar";
$Regions = "Regiones";
$CourseList = "Lista de cursos";
$NumberAbbreviation = "N°";
$FirstnameAndLastname = "Nombres y Apellidos";
$LastnameAndFirstname = "Apellidos y Nombres";
$Plugins = "Plugins";
$Detailed = "Detallado";
$ResourceLockedByGradebook = "Esta opción no está disponible porque la actividad está incluida en una evaluación que se encuentra bloqueada. Para desbloquear esta evaluación, comuníquese con el administrador de la plataforma.";
?>

@ -38,7 +38,7 @@ $(document).ready(function() {
$("#dialog-form").dialog({
autoOpen: false,
modal : false,
width : 550,
width : 580,
height : 480,
zIndex: 20000 // added because of qtip2
});
@ -46,7 +46,7 @@ $(document).ready(function() {
$("#simple-dialog-form").dialog({
autoOpen: false,
modal : false,
width : 550,
width : 580,
height : 480,
zIndex: 20000 // added because of qtip2
});
@ -164,7 +164,7 @@ $(document).ready(function() {
$('#color_calendar').html('{{type_label}}');
$('#color_calendar').removeClass('group_event');
$('#color_calendar').addClass('label_tag');
$('#color_calendar').addClass('{{type}}_event');
$('#color_calendar').addClass('{{ type_event_class }}');
allFields.removeClass( "ui-state-error" );
$("#dialog-form").dialog("open");

@ -3367,7 +3367,8 @@ $server->wsdl->addComplexType(
'',
'SOAP-ENC:Array',
array(),
array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType' => 'tns:originalUsersList[]')),'xsd:string'
array(array('ref' => 'SOAP-ENC:arrayType', 'wsdl:arrayType' => 'tns:deleteSessionParams[]')),
'tns:originalUsersList'
);
$server->wsdl->addComplexType(

Loading…
Cancel
Save