1.9.x
Julio Montoya 12 years ago
commit b42a761156
  1. 167
      main/admin/extra_field_options.php
  2. 212
      main/admin/extra_field_workflow.php
  3. 218
      main/admin/extra_fields.php
  4. 2
      main/admin/specific_fields_add.php
  5. 27
      main/announcements/announcement_email.class.php
  6. 31
      main/announcements/announcements.inc.php
  7. 12
      main/announcements/announcements.php
  8. 219
      main/course_description/course_description_controller.php
  9. 5
      main/document/document.php
  10. 92
      main/exercice/exercise.class.php
  11. 20
      main/exercice/exercise.lib.php
  12. 2
      main/exercice/exercise_show.php
  13. 110
      main/inc/ajax/course.ajax.php
  14. 14
      main/inc/ajax/course_home.ajax.php
  15. 30
      main/inc/ajax/extra_field.ajax.php
  16. 160
      main/inc/ajax/model.ajax.php
  17. 29
      main/inc/ajax/session.ajax.php
  18. 2
      main/inc/global_error_message.inc.php
  19. 6
      main/inc/introductionSection.inc.php
  20. 5
      main/inc/lib/autoload.class.php
  21. 31
      main/inc/lib/course.lib.php
  22. 4
      main/inc/lib/database.constants.inc.php
  23. 45
      main/inc/lib/display.lib.php
  24. 21
      main/inc/lib/document.lib.php
  25. 29
      main/inc/lib/events.lib.inc.php
  26. 41
      main/inc/lib/export.lib.inc.php
  27. 1648
      main/inc/lib/extra_field.lib.php
  28. 659
      main/inc/lib/extra_field_option.lib.php
  29. 654
      main/inc/lib/extra_field_value.lib.php
  30. 1
      main/inc/lib/fckeditor/editor/plugins/ImageManager/config.inc.php
  31. 36
      main/inc/lib/fileUpload.lib.php
  32. 22
      main/inc/lib/formvalidator/Element/select_ajax.php
  33. 8
      main/inc/lib/main_api.lib.php
  34. 16
      main/inc/lib/pear/HTML/QuickForm.php
  35. 3168
      main/inc/lib/sessionmanager.lib.php
  36. 653
      main/inc/lib/tracking.lib.php
  37. 21
      main/inc/lib/usermanager.lib.php
  38. 8
      main/inc/local.inc.php
  39. 19
      main/lang/english/admin.inc.php
  40. 48
      main/lang/english/exercice.inc.php
  41. 73
      main/lang/spanish/admin.inc.php
  42. 8
      main/lang/spanish/tracking.inc.php
  43. 1
      main/lang/spanish_latin/trad4all.inc.php
  44. 6
      main/mySpace/lp_tracking.php
  45. 40
      main/mySpace/myStudents.php
  46. 301
      main/mySpace/myspace.lib.php
  47. 2
      main/newscorm/learnpathList.class.php
  48. 10
      main/newscorm/lp_ajax_save_item.php
  49. 6
      main/newscorm/lp_controller.php
  50. 26
      main/newscorm/lp_edit.php
  51. 10
      main/newscorm/lp_stats.php
  52. 22
      main/newscorm/scorm_api.php
  53. 11
      main/session/index.php

@ -0,0 +1,167 @@
<?php
/* For licensing terms, see /license.txt */
/**
* @package chamilo.admin
*/
// Language files that need to be included.
$language_file = array('admin');
$cidReset = true;
require_once '../inc/global.inc.php';
$this_section = SECTION_PLATFORM_ADMIN;
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
api_protect_admin_script();
//Add the JS needed to use the jqgrid
$htmlHeadXtra[] = api_get_jqgrid_js();
// setting breadcrumbs
$interbreadcrumb[]=array('url' => 'index.php','name' => get_lang('PlatformAdmin'));
$tool_name = null;
$action = isset($_GET['action']) ? $_GET['action'] : null;
$field_id = isset($_GET['field_id']) ? $_GET['field_id'] : null;
if (empty($field_id)) {
api_not_allowed();
}
if (!in_array($type, ExtraField::getValidExtraFieldTypes())) {
api_not_allowed();
}
$extra_field = new ExtraField($type);
$extra_field_info = $extra_field->get($field_id);
$check = Security::check_token('request');
$token = Security::get_token();
if ($action == 'add') {
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type,'name' => $extra_field->pageName);
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type.'&action=edit&id='.$extra_field_info['id'],'name' => $extra_field_info['field_display_text']);
$interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extra_field->type.'&field_id='.$extra_field_info['id'], 'name' => get_lang('EditExtraFieldOptions'));
$interbreadcrumb[]=array('url' => '#','name' => get_lang('Add'));
} elseif ($action == 'edit') {
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type,'name' => $extra_field->pageName);
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type.'&action=edit&id='.$extra_field_info['id'],'name' => $extra_field_info['field_display_text']);
$interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extra_field->type.'&field_id='.$extra_field_info['id'], 'name' => get_lang('EditExtraFieldOptions'));
$interbreadcrumb[]=array('url' => '#','name' => get_lang('Edit'));
} else {
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type,'name' => $extra_field->pageName);
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extra_field->type.'&action=edit&id='.$extra_field_info['id'],'name' => $extra_field_info['field_display_text']);
$interbreadcrumb[]=array('url' => '#','name' => get_lang('EditExtraFieldOptions'));
}
//jqgrid will use this URL to do the selects
$params = 'field_id='.$field_id.'&type='.$extra_field->type;
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_extra_field_options&'.$params;
//The order is important you need to check the the $column variable in the model.ajax.php file
$columns = array(get_lang('Name'), get_lang('Value'), get_lang('Order'), get_lang('Actions'));
//Column config
$column_model = array(
array('name'=>'option_display_text', 'index'=>'option_display_text', 'width'=>'180', 'align'=>'left'),
array('name'=>'option_value', 'index'=>'option_value', 'width'=>'', 'align'=>'left','sortable'=>'false'),
array('name'=>'option_order', 'index'=>'option_order', 'width'=>'', 'align'=>'left','sortable'=>'false'),
array('name'=>'actions', 'index'=>'actions', 'width'=>'100', 'align'=>'left','formatter'=>'action_formatter','sortable'=>'false')
);
//Autowidth
$extra_params['autowidth'] = 'true';
//height auto
$extra_params['height'] = 'auto';
//With this function we can add actions to the jgrid (edit, delete, etc)
$action_links = 'function action_formatter(cellvalue, options, rowObject) {
return \'<a href="?action=edit&'.$params.'&id=\'+options.rowId+\'">'.Display::return_icon('edit.png',get_lang('Edit'),'',ICON_SIZE_SMALL).'</a>'.
'&nbsp;<a onclick="javascript:if(!confirm('."\'".addslashes(get_lang("ConfirmYourChoice"))."\'".')) return false;" href="?sec_token='.$token.'&action=delete&'.$params.'&id=\'+options.rowId+\'">'.Display::return_icon('delete.png',get_lang('Delete'),'',ICON_SIZE_SMALL).'</a>'.
'\';
}';
$htmlHeadXtra[]='
<script>
$(function() {
// grid definition see the $obj->display() function
'.Display::grid_js('extra_field_options', $url, $columns, $column_model, $extra_params, array(), $action_links, true).'
});
</script>';
// The header.
Display::display_header($tool_name);
echo Display::page_header($extra_field_info['field_display_text']);
$obj = new ExtraFieldOption($extra_field->type);
$obj->field_id = $field_id;
// Action handling: Add
switch ($action) {
case 'add':
if (api_get_session_id() != 0 && !api_is_allowed_to_session_edit(false, true)) {
api_not_allowed();
}
$url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&'.$params;
$form = $obj->return_form($url, 'add');
// The validation or display
if ($form->validate()) {
if ($check) {
$values = $form->exportValues();
$res = $obj->save_one_item($values);
if ($res) {
Display::display_confirmation_message(get_lang('ItemAdded'));
}
}
$obj->display();
} else {
/*echo '<div class="actions">';
echo '<a href="'.api_get_self().'">'.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).'</a>';
echo '</div>'; */
$form->addElement('hidden', 'sec_token');
$form->setConstants(array('sec_token' => $token));
$form->display();
}
break;
case 'edit':
// Action handling: Editing
$url = api_get_self().'?action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']).'&'.$params;
$form = $obj->return_form($url, 'edit');
// The validation or display
if ($form->validate()) {
if ($check) {
$values = $form->exportValues();
$res = $obj->update($values);
Display::display_confirmation_message(sprintf(get_lang('ItemUpdated'), $values['name']), false);
}
$obj->display();
} else {
/*echo '<div class="actions">';
echo '<a href="'.api_get_self().'">'.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).'</a>';
echo '</div>';*/
$form->addElement('hidden', 'sec_token');
$form->setConstants(array('sec_token' => $token));
$form->display();
}
break;
case 'delete':
// Action handling: delete
if ($check) {
$res = $obj->delete($_GET['id']);
if ($res) {
Display::display_confirmation_message(get_lang('ItemDeleted'));
}
}
$obj->display();
break;
default:
$obj->display();
break;
}
Display :: display_footer();

@ -0,0 +1,212 @@
<?php
/* For licensing terms, see /license.txt */
/**
* @package chamilo.admin
*/
// Language files that need to be included.
$language_file = array('admin');
$cidReset = true;
require_once '../inc/global.inc.php';
$this_section = SECTION_PLATFORM_ADMIN;
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
api_protect_admin_script();
// setting breadcrumbs
$interbreadcrumb[] = array('url' => 'index.php','name' => get_lang('PlatformAdmin'));
$tool_name = null;
$action = isset($_GET['action']) ? $_GET['action'] : null;
$field_id = isset($_GET['field_id']) ? $_GET['field_id'] : null;
if (empty($field_id)) {
api_not_allowed();
}
if (!in_array($type, ExtraField::getValidExtraFieldTypes())) {
api_not_allowed();
}
$extraField = new ExtraField($type);
$extraFieldInfo = $extraField->get($field_id);
$check = Security::check_token('request');
$token = Security::get_token();
if ($action == 'add') {
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type,'name' => $extraField->pageName);
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type.'&action=edit&id='.$extraFieldInfo['id'],'name' => $extraFieldInfo['field_display_text']);
$interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extraField->type.'&field_id='.$extraFieldInfo['id'], 'name' => get_lang('EditExtraFieldOptions'));
$interbreadcrumb[]=array('url' => '#','name' => get_lang('Add'));
} elseif ($action == 'edit') {
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type,'name' => $extraField->pageName);
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type.'&action=edit&id='.$extraFieldInfo['id'],'name' => $extraFieldInfo['field_display_text']);
$interbreadcrumb[]=array('url' => 'extra_field_options.php?type='.$extraField->type.'&field_id='.$extraFieldInfo['id'], 'name' => get_lang('EditExtraFieldOptions'));
$interbreadcrumb[]=array('url' => '#','name' => get_lang('Edit'));
} else {
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type,'name' => $extraField->pageName);
$interbreadcrumb[]=array('url' => 'extra_fields.php?type='.$extraField->type.'&action=edit&id='.$extraFieldInfo['id'],'name' => $extraFieldInfo['field_display_text']);
$interbreadcrumb[]=array('url' => '#','name' => get_lang('EditExtraFieldOptions'));
}
$roleId = isset($_REQUEST['roleId']) ? $_REQUEST['roleId'] : null;
//jqgrid will use this URL to do the selects
$params = 'field_id='.$field_id.'&type='.$extraField->type.'&roleId='.$roleId;
$paramsNoRole = 'field_id='.$field_id.'&type='.$extraField->type;
//The order is important you need to check the the $column variable in the model.ajax.php file
$columns = array(get_lang('Name'), get_lang('Value'), get_lang('Order'), get_lang('Actions'));
$htmlHeadXtra[]='<script>
function setHidden(obj) {
var name = $(obj).attr("name");
var hiddenName = "hidden_" + name;
if ($("#" + hiddenName).attr("value") == 1) {
$("#" + hiddenName).attr("value", 0);
} else {
$("#" + hiddenName).attr("value", 1);
}
}
function changeStatus(obj) {
var roleId = $(obj).find(":selected").val();
if (roleId != 0) {
window.location.replace("'.api_get_self().'?'.$paramsNoRole.'&roleId="+roleId);
}
}
$().ready( function() {
$(".select_all").on("click", function() {
$("#workflow :checkbox").prop("checked", 1);
$("#workflow :hidden").prop("value", 1);
return false;
});
$(".unselect_all").on("click", function() {
$("#workflow :checkbox").prop("checked", 0);
$("#workflow :hidden").prop("value", 0);
return false;
});
});
</script>';
// The header.
Display::display_header($tool_name);
echo Display::page_header($extraFieldInfo['field_display_text']);
$obj = new ExtraFieldOption($type);
$columns = array('option_display_text', 'option_value', 'option_order');
$result = Database::select('*', $obj->table, array('where' => array("field_id = ? " => $field_id), 'order'=>"option_order ASC"));
$table = new HTML_Table(array('class' => 'data_table'));
$column = 0;
$row = 0;
$table->setHeaderContents($row, $column, get_lang('CurrentStatus'));
$column++;
foreach ($result as $item) {
$table->setHeaderContents($row, $column, $item['option_display_text']);
$column++;
}
$row++;
$form = new FormValidator('workflow', 'post', api_get_self().'?'.$params);
$options = api_get_user_roles();
$options[0] = get_lang('SelectAnOption');
ksort($options);
$form->addElement('select', 'status', get_lang('SelectRole'), $options, array('onclick' => 'changeStatus(this)'));
$checks = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')->findBy(array('fieldId' => $field_id, 'roleId' => $roleId));
$includedFields = array();
if (!empty($checks)) {
foreach ($checks as $availableField) {
$includedFields[$availableField->getFieldOptionId()][] = $availableField->getRelatedFieldOptionId();
}
}
foreach ($result as $item) {
$column = 0;
$table->setCellContents($row, $column, $item['option_display_text']);
$column++;
$value = null;
foreach ($result as $itemCol) {
$id = 'extra_field_status_'.$item['id'].'_'.$itemCol['id'];
$idForm = 'extra_field_status['.$item['id'].']['.$itemCol['id'].']';
$attributes = array('onclick' => 'setHidden(this)');
$value = 0;
if (isset($includedFields[$itemCol['id']]) && in_array($item['id'], $includedFields[$itemCol['id']])) {
$value = 1;
$attributes['checked'] = 'checked';
}
$element = Display::input('checkbox', $id, null, $attributes);
$table->setCellContents($row, $column, $element);
$form->addElement('hidden', 'hidden_'.$idForm, $value, array('id' => 'hidden_'.$id));
$column++;
}
$row++;
}
if (!empty($roleId)) {
$form->addElement('html', $table->toHtml());
$group = array();
$group[]= $form->createElement('button', 'submit', get_lang('Save'));
$group[]= $form->createElement('button', 'select_all', get_lang('SelectAll'), array('class' => 'btn select_all'));
$group[]= $form->createElement('button', 'unselect_all', get_lang('UnSelectAll'), array('class' => 'btn unselect_all'));
$form->addGroup($group, '', null, ' ');
$form->setDefaults(array('status' => $roleId));
} else {
$form->addElement('button', 'submit', get_lang('Edit'));
}
$form->display();
if ($form->validate()) {
$values = $form->getSubmitValues();
$result = $values['hidden_extra_field_status'];
if (!empty($result)) {
foreach ($result as $id => $items) {
foreach ($items as $subItemId => $value) {
$extraFieldOptionRelFieldOption = $app['orm.em']->getRepository('ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption')->findOneBy(
array(
'fieldId' => $field_id,
'fieldOptionId' => $subItemId,
'roleId' => $roleId,
'relatedFieldOptionId' => $id
)
);
if ($value == 1) {
if (empty($extraFieldOptionRelFieldOption)) {
$extraFieldOptionRelFieldOption = new \ChamiloLMS\Entity\ExtraFieldOptionRelFieldOption();
$extraFieldOptionRelFieldOption->setFieldId($field_id);
$extraFieldOptionRelFieldOption->setFieldOptionId($subItemId);
$extraFieldOptionRelFieldOption->setRelatedFieldOptionId($id);
$extraFieldOptionRelFieldOption->setRoleId($roleId);
$app['orm.ems']['db_write']->persist($extraFieldOptionRelFieldOption);
}
} else {
if ($extraFieldOptionRelFieldOption) {
$app['orm.ems']['db_write']->remove($extraFieldOptionRelFieldOption);
}
}
}
}
$app['orm.ems']['db_write']->flush();
header('Location:'.api_get_self().'?'.$params);
exit;
}
}
Display :: display_footer();

@ -0,0 +1,218 @@
<?php
/* For licensing terms, see /license.txt */
/**
* @package chamilo.admin
*/
// Language files that need to be included.
$language_file = array('admin');
$cidReset = true;
$cidReset = true;
require_once '../inc/global.inc.php';
$extraFieldType = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$this_section = SECTION_PLATFORM_ADMIN;
api_protect_admin_script();
//Add the JS needed to use the jqgrid
$htmlHeadXtra[] = api_get_jqgrid_js();
// setting breadcrumbs
$interbreadcrumb[]=array('url' => 'index.php','name' => get_lang('PlatformAdmin'));
$tool_name = null;
$action = isset($_GET['action']) ? $_GET['action'] : null;
if (!in_array($extraFieldType, ExtraField::getValidExtraFieldTypes())) {
api_not_allowed();
}
$check = Security::check_token('request');
$token = Security::get_token();
$obj = new ExtraField($extraFieldType);
$obj->setupBreadcrumb($interbreadcrumb, $action);
//jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_extra_fields&type='.$extraFieldType;
//The order is important you need to check the the $column variable in the model.ajax.php file
$columns = $obj->getJqgridColumnNames();
//Column config
$column_model = $obj->getJqgridColumnModel();
//Autowidth
$extra_params['autowidth'] = 'true';
//height auto
$extra_params['height'] = 'auto';
$extra_params['sortname'] = 'field_order';
$action_links = $obj->getJqgridActionLinks($token);
$htmlHeadXtra[]='<script>
$(function() {
// grid definition see the $obj->display() function
'.Display::grid_js($obj->type.'_fields', $url, $columns, $column_model, $extra_params, array(), $action_links, true).'
$("#field_type").on("change", function() {
id = $(this).val();
switch(id) {
case "1":
$("#example").html("'.addslashes(Display::return_icon('userfield_text.png')).'");
break;
case "2":
$("#example").html("'.addslashes(Display::return_icon('userfield_text_area.png')).'");
break;
case "3":
$("#example").html("'.addslashes(Display::return_icon('add_user_field_howto.png')).'");
break;
case "4":
$("#example").html("'.addslashes(Display::return_icon('userfield_drop_down.png')).'");
break;
case "5":
$("#example").html("'.addslashes(Display::return_icon('userfield_multidropdown.png')).'");
break;
case "6":
$("#example").html("'.addslashes(Display::return_icon('userfield_data.png')).'");
break;
case "7":
$("#example").html("'.addslashes(Display::return_icon('userfield_date_time.png')).'");
break;
case "8":
$("#example").html("'.addslashes(Display::return_icon('userfield_doubleselect.png')).'");
break;
case "9":
$("#example").html("'.addslashes(Display::return_icon('userfield_divider.png')).'");
break;
case "10":
$("#example").html("'.addslashes(Display::return_icon('userfield_user_tag.png')).'");
break;
case "11":
$("#example").html("'.addslashes(Display::return_icon('userfield_data.png')).'");
break;
}
});
});
</script>';
// The header.
Display::display_header($tool_name);
// Action handling: Add
switch ($action) {
case 'add':
if (api_get_session_id() != 0 && !api_is_allowed_to_session_edit(false, true)) {
api_not_allowed();
}
$url = api_get_self().'?type='.$obj->type.'&action='.Security::remove_XSS($_GET['action']);
$form = $obj->return_form($url, 'add');
// The validation or display
if ($form->validate()) {
//if ($check) {
$values = $form->exportValues();
$res = $obj->save($values);
if ($res) {
Display::display_confirmation_message(get_lang('ItemAdded'));
}
//}
$obj->display();
} else {
echo '<div class="actions">';
echo '<a href="'.api_get_self().'?type='.$obj->type.'">'.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
$form->addElement('hidden', 'sec_token');
$form->setConstants(array('sec_token' => $token));
$form->display();
}
break;
case 'edit':
// Action handling: Editing
$url = api_get_self().'?type='.$obj->type.'&action='.Security::remove_XSS($_GET['action']).'&id='.intval($_GET['id']);
$form = $obj->return_form($url, 'edit');
// The validation or display
if ($form->validate()) {
//if ($check) {
$values = $form->exportValues();
$res = $obj->update($values);
Display::display_confirmation_message(sprintf(get_lang('ItemUpdated'), $values['field_variable']), false);
//}
$obj->display();
} else {
echo '<div class="actions">';
echo '<a href="'.api_get_self().'?type='.$obj->type.'">'.Display::return_icon('back.png',get_lang('Back'),'',ICON_SIZE_MEDIUM).'</a>';
echo '</div>';
$form->addElement('hidden', 'sec_token');
$form->setConstants(array('sec_token' => $token));
$form->display();
}
break;
case 'delete':
// Action handling: delete
//if ($check) {
$res = $obj->delete($_GET['id']);
if ($res) {
Display::display_confirmation_message(get_lang('ItemDeleted'));
}
//}
$obj->display();
break;
default:
$obj->display();
break;
}
Display :: display_footer();
/*
CREATE TABLE IF NOT EXISTS lp_field(
id INT NOT NULL auto_increment,
field_type int NOT NULL DEFAULT 1,
field_variable varchar(64) NOT NULL,
field_display_text varchar(64),
field_default_value text,
field_order int,
field_visible tinyint default 0,
field_changeable tinyint default 0,
field_filter tinyint default 0,
tms DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY(id)
);
DROP TABLE IF EXISTS lp_field_options;
CREATE TABLE IF NOT EXISTS lp_field_options (
id int NOT NULL auto_increment,
field_id int NOT NULL,
option_value text,
option_display_text varchar(64),
option_order int,
tms DATETIME NOT NULL default '0000-00-00 00:00:00',
priority VARCHAR(255),
priority_message VARCHAR(255),
PRIMARY KEY (id)
);
DROP TABLE IF EXISTS lp_field_values;
CREATE TABLE IF NOT EXISTS lp_field_values(
id bigint NOT NULL auto_increment,
lp_id int unsigned NOT NULL,
field_id int NOT NULL,
field_value text,
comment VARCHAR(100) default '',
tms DATETIME NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY(id)
);
ALTER TABLE lp_field_values ADD INDEX (lp_id, field_id);
*/

@ -74,4 +74,4 @@ if ($form->validate()) {
// Display form
Display::display_header($tool_name);
$form->display();
Display::display_footer();
Display::display_footer();

@ -220,13 +220,16 @@ class AnnouncementEmail
*/
public function message($receiverUserId)
{
//$title = $this->announcement('title');
$content = $this->announcement('content');
$content = stripslashes($content);
$content = AnnouncementManager::parse_content($receiverUserId, $content, $this->course('code'));
$content = AnnouncementManager::parse_content($content, $this->course('code'), $session_id);
$session_id = $this->session_id;
$user_email = $this->sender('mail');
$course_param = api_get_cidreq();
//$course_param = api_get_cidreq();
// Build the link by hand because api_get_cidreq() doesn't accept course params
$course_param = 'cidReq='.api_get_course_id().'&amp;id_session='.$session_id.'&amp;gidReq='.api_get_group_id();
$course_name = $this->course('title');
$result = "<div>$content</div>";
@ -277,7 +280,7 @@ class AnnouncementEmail
/**
* Send emails to users.
*/
public function send()
public function send($sendToUsersInSession = false)
{
$sender = $this->sender();
$subject = $this->subject();
@ -294,6 +297,22 @@ class AnnouncementEmail
$sender['user_id']
);
}
if ($sendToUsersInSession) {
$sessionList = SessionManager::get_session_by_course($this->course['code']);
if (!empty($sessionList)) {
foreach ($sessionList as $sessionInfo) {
$sessionId = $sessionInfo['id'];
$message = $this->message(null, $sessionId);
$userList = CourseManager::get_user_list_from_course_code($this->course['code'], $sessionId);
if (!empty($userList)) {
foreach ($userList as $user) {
MessageManager::send_message_simple($user['user_id'], $subject, $message, $sender['user_id']);
}
}
}
}
}
$this->log_mail_sent();
}

@ -1,15 +1,11 @@
<?php
/* For licensing terms, see /license.txt */
/**
*/
/**
* Include file with functions for the announcements module.
* @author jmontoya
* @package chamilo.announcements
* @todo use OOP
*
*/
class AnnouncementManager
{
@ -42,7 +38,7 @@ class AnnouncementManager
*
* @return mixed
*/
public static function parse_content($userId, $content, $course_code)
public static function parse_content($userId, $content, $course_code, $session_id = 0)
{
$readerInfo = api_get_user_info($userId);
$courseInfo = api_get_course_info($course_code);
@ -56,8 +52,8 @@ class AnnouncementManager
break;
}
}
$course_link = api_get_course_url($course_code, $session_id);
$courseLink = api_get_course_url();
$data['user_name'] = $readerInfo['username'];
$data['user_firstname'] = $readerInfo['firstname'];
$data['user_lastname'] = $readerInfo['lastname'];
@ -236,7 +232,7 @@ class AnnouncementManager
echo "<tr><th style='text-align:right'>$modify_icons</th></tr>";
}
$content = self::parse_content($result['to_user_id'], $content, api_get_course_id());
$content = self::parse_content($result['to_user_id'], $content, api_get_course_id(), api_get_session_id());
echo "<tr><td>$content</td></tr>";
@ -366,13 +362,15 @@ class AnnouncementManager
api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", api_get_user_id(), '', $user);
}
}
} else {
// the message is sent to everyone, so we set the group to 0
api_item_property_update($_course, TOOL_ANNOUNCEMENT, $last_id, "AnnouncementAdded", api_get_user_id(), '0');
}
if ($sendToUsersInSession) {
self::addAnnouncementToAllUsersInSessions($last_id);
}
return $last_id;
}
}
@ -490,6 +488,11 @@ class AnnouncementManager
$sql_delete = "DELETE FROM $tbl_item_property WHERE c_id = $course_id AND ref='$id' AND tool='announcement'";
Database::query($sql_delete);
if ($sendToUsersInSession) {
self::addAnnouncementToAllUsersInSessions($id);
}
if ($sendToUsersInSession) {
self::addAnnouncementToAllUsersInSessions($id);
}
@ -552,7 +555,6 @@ class AnnouncementManager
}
}
}
}
/**
@ -709,7 +711,7 @@ class AnnouncementManager
*/
public static function construct_not_selected_select_form($group_list = null, $user_list = null, $to_already_selected)
{
echo '<select id="not_selected_form" name="not_selected_form[]" size="7" class="span4" multiple>';
echo '<select name="not_selected_form[]" size="7" class="span4" multiple>';
// adding the groups to the select form
if ($group_list) {
foreach ($group_list as $this_group) {
@ -1208,12 +1210,9 @@ class AnnouncementManager
Database::query($sql);
}
/**
* @param int $id
*/
public static function send_email($id)
public static function send_email($annoucement_id, $sendToUsersInSession = false)
{
$email = AnnouncementEmail::create(null, $id);
$email->send();
$email = AnnouncementEmail::create(null, $annoucement_id);
$email->send($sendToUsersInSession);
}
}

@ -365,7 +365,7 @@ if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_ed
/* MAIL FUNCTION */
if ($_POST['email_ann'] && empty($_POST['onlyThoseMails'])) {
AnnouncementManager::send_email($id);
AnnouncementManager::send_email($id, $sendToUsersInSession);
}
$message = get_lang('AnnouncementModified');
}
@ -385,7 +385,7 @@ if (api_is_allowed_to_edit(false,true) OR (api_get_course_setting('allow_user_ed
/* MAIL FUNCTION */
if ($_POST['email_ann'] && empty($_POST['onlyThoseMails'])) {
AnnouncementManager::send_email($insert_id);
AnnouncementManager::send_email($insert_id, $sendToUsersInSession);
}
} // end condition token
@ -647,9 +647,11 @@ if ($display_form) {
echo ' </div>
</div>';
echo '<div class="control-group"><div class="controls">';
echo '<label class="checkbox" ><input name="send_to_users_in_session" type="checkbox" />'.get_lang('SendToUsersInSessions').'</label>';
echo '</div></div>';
if (api_get_session_id() == 0) {
echo '<div class="control-group"><div class="controls">';
echo '<label class="checkbox" ><input name="send_to_users_in_session" type="checkbox" />'.get_lang('SendToUsersInSessions').'</label>';
echo '</div></div>';
}
if (!isset($announcement_to_modify) ) $announcement_to_modify ='';

@ -37,123 +37,122 @@ class CourseDescriptionController { // extends Controller {
$course_description->set_session_id($session_id);
$data = array();
$course_description_data = $course_description->get_description_data();
$data['descriptions'] = $course_description_data['descriptions'];
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['messages'] = $messages;
// Fix for chrome XSS filter for videos in iframes - BT#7930
$course_description_data = $course_description->get_description_data();
$data['descriptions'] = $course_description_data['descriptions'];
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['messages'] = $messages;
$browser = api_get_navigator();
if (strpos($data['descriptions'], '<iframe') !== false && $browser['name'] == 'Chrome') {
header('X-XSS-Protection: 0');
header("X-XSS-Protection: 0");
}
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('listing');
$this->view->render();
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('listing');
$this->view->render();
}
/**
* It's used for editing a course description,
* render to listing or edit view
* @param int description type
*/
public function edit($id, $description_type) {
$course_description = new CourseDescription();
$session_id = api_get_session_id();
$course_description->set_session_id($session_id);
$data = array();
$data['id'] = $id;
if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") {
if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) {
$check = Security::check_token();
if ($check) {
$title = $_POST['title'];
if (api_get_setting('wcag_anysurfer_public_pages')=='true') {
$content = WCAG_Rendering::prepareXHTML();
} else {
$content = $_POST['contentDescription'];
}
$description_type = $_POST['description_type'];
$id = $_POST['id'];
$progress = $_POST['progress'];
$course_description->set_description_type($description_type);
$course_description->set_title($title);
$course_description->set_content($content);
$course_description->set_progress($progress);
$thematic_advance = $course_description->get_data_by_id($id);
if (!empty($thematic_advance)) {
$course_description->set_id($id);
$affected_rows = $course_description->update();
} else {
$affected_rows = $course_description->insert();
/**
* It's used for editing a course description,
* render to listing or edit view
* @param int description type
*/
public function edit($id, $description_type)
{
$course_description = new CourseDescription();
$session_id = api_get_session_id();
$course_description->set_session_id($session_id);
$data = array();
$data['id'] = $id;
if (strtoupper($_SERVER['REQUEST_METHOD']) == "POST") {
if (!empty($_POST['title']) && !empty($_POST['contentDescription'])) {
$check = Security::check_token();
if ($check) {
$title = $_POST['title'];
if (api_get_setting('wcag_anysurfer_public_pages') == 'true') {
$content = WCAG_Rendering::prepareXHTML();
} else {
$content = $_POST['contentDescription'];
}
$description_type = $_POST['description_type'];
$id = $_POST['id'];
$progress = $_POST['progress'];
$course_description->set_description_type($description_type);
$course_description->set_title($title);
$course_description->set_content($content);
$course_description->set_progress($progress);
$thematic_advance = $course_description->get_data_by_id($id);
if (!empty($thematic_advance)) {
$course_description->set_id($id);
$affected_rows = $course_description->update();
} else {
$affected_rows = $course_description->insert();
}
Security::clear_token();
}
Security::clear_token();
}
if ($affected_rows) {
$message['edit'] = true;
}
$this->listing(false,$message);
} else {
$data['error'] = 1;
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_title'] = $_POST['title'];
$data['description_content'] = $_POST['contentDescription'];
$data['description_type'] = $_POST['description_type'];
$data['progress'] = $_POST['progress'];
$data['descriptions'] = $course_description->get_data_by_id($_POST['id']);
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('edit');
$this->view->render();
}
} else {
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_type'] = $description_type;
if (!empty($id)) {
if (isset($_GET['id_session'])) {
$session_id = intval($_GET['id_session']);
}
$course_description_data = $course_description->get_data_by_id($id, null, $session_id);
$data['description_type'] = $course_description_data['description_type'];
$data['description_title'] = $course_description_data['description_title'];
$data['description_content'] = $course_description_data['description_content'];
$data['progress'] = $course_description_data['progress'];
$data['descriptions'] = $course_description->get_data_by_description_type($description_type, null, $session_id);
}
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('edit');
$this->view->render();
if ($affected_rows) {
$message['edit'] = true;
}
$this->listing(false, $message);
} else {
$data['error'] = 1;
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_title'] = $_POST['title'];
$data['description_content'] = $_POST['contentDescription'];
$data['description_type'] = $_POST['description_type'];
$data['progress'] = $_POST['progress'];
$data['descriptions'] = $course_description->get_data_by_id($_POST['id']);
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('edit');
$this->view->render();
}
} else {
$data['default_description_titles'] = $course_description->get_default_description_title();
$data['default_description_title_editable'] = $course_description->get_default_description_title_editable();
$data['default_description_icon'] = $course_description->get_default_description_icon();
$data['question'] = $course_description->get_default_question();
$data['information'] = $course_description->get_default_information();
$data['description_type'] = $description_type;
if (!empty($id)) {
if (isset($_GET['id_session'])) {
$session_id = intval($_GET['id_session']);
}
$course_description_data = $course_description->get_data_by_id($id, null, $session_id);
$data['description_type'] = $course_description_data['description_type'];
$data['description_title'] = $course_description_data['description_title'];
$data['description_content'] = $course_description_data['description_content'];
$data['progress'] = $course_description_data['progress'];
$data['descriptions'] = $course_description->get_data_by_description_type($description_type, null, $session_id);
}
// render to the view
$this->view->set_data($data);
$this->view->set_layout('layout');
$this->view->set_template('edit');
$this->view->render();
}
}
}
/**
/**
* It's used for adding a course description,
* render to listing or add view
*/

@ -1510,11 +1510,13 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) {
if ($groupId == 0 || GroupManager::user_has_access($userId, $groupId, GroupManager::GROUP_TOOL_DOCUMENTS)) {
$count = 1;
$countedPaths = array();
$countedPaths = array();
foreach ($documentAndFolders as $key => $document_data) {
$row = array();
$row['id'] = $document_data['id'];
$row['type'] = $document_data['filetype'];
// If the item is invisible, wrap it in a span with class invisible.
$is_visible = DocumentManager::is_visible_by_id(
$document_data['id'],
@ -1606,6 +1608,7 @@ if (isset($documentAndFolders) && is_array($documentAndFolders)) {
$row[] = $size;
$row[] = $document_name;
$total_size = $total_size + $size;
if (!isset($countedPaths[$document_data['path']])) {
$total_size = $total_size + $size;
$countedPaths[$document_data['path']] = true;

@ -3410,6 +3410,7 @@ class Exercise
);
return $return_array;
}
/**
* Sends a notification when a user ends an examn
*
@ -3911,13 +3912,13 @@ class Exercise
$isRandomByCategory = $this->selectRandomByCat();
// on tri les categories en fonction du terme entre [] en tete de la description de la categorie
/*
* ex de catégories :
* ex de catégories :
* [biologie] Maitriser les mecanismes de base de la genetique
* [biologie] Relier les moyens de depenses et les agents infectieux
* [biologie] Savoir ou est produite l'enrgie dans les cellules et sous quelle forme
* [chimie] Classer les molles suivant leur pouvoir oxydant ou reacteur
* [chimie] Connaître la denition de la theoie acide/base selon Brönsted
* [chimie] Connaître les charges des particules
* [chimie] Connaître la denition de la theoie acide/base selon Brönsted
* [chimie] Connaître les charges des particules
* On veut dans l'ordre des groupes definis par le terme entre crochet au debut du titre de la categorie
*/
// If test option is Grouped By Categories
@ -4179,8 +4180,8 @@ class Exercise
}
/**
* @return string
*/
* @return string
*/
public function get_formated_title()
{
return api_html_entity_decode($this->selectTitle());
@ -4212,5 +4213,86 @@ class Exercise
{
return api_htmlentities($in_title);
}
/**
* @param int courseid
* @param int sessionid
* @return array exercises
*/
public function getExercisesByCouseSession($courseId, $sessionId)
{
$tbl_quiz = Database::get_course_table(TABLE_QUIZ_TEST);
$sql = "SELECT * FROM $tbl_quiz cq "
. "WHERE "
. "cq.c_id = %s AND "
. "( cq.session_id = %s OR cq.session_id = 0 ) AND "
. "cq.active = 0 "
. "ORDER BY cq.id";
$sql = sprintf($sql, $courseId, $sessionId);
$result = Database::query($sql);
$rows = array();
while($row = Database::fetch_array($result, 'ASSOC')) {
$rows[] = $row;
}
return $rows;
}
/**
* @param int courseid
* @param int sessionid
* @param array quizId
* @return array exercises
*/
public function getExerciseAndResult($courseId, $sessionId, $quizId = array())
{
if (empty($quizId)) {
return array();
}
$ids = is_array($quizId) ? $quizId : array($quizId);
$ids = array_map('intval', $quizId);
$ids = implode(',', $quizId);
$tbl_quiz = Database::get_course_table(TABLE_QUIZ_TEST);
$track_exercises = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$whSession = "";
if ($sessionId != 0) {
$sql = "SELECT * FROM $track_exercises te "
. "INNER JOIN c_quiz cq ON cq.id = te.exe_exo_id "
. "INNER JOIN course c ON te.exe_cours_id = c.code AND c.id = cq.c_id "
. "WHERE "
. "c.id = %s AND "
. "te.session_id = %s AND "
. "cq.id IN (%s) "
. "ORDER BY cq.id ";
$sql = sprintf($sql, $courseId, $sessionId, $ids);
$whSession = "te.session_id = %s AND ";
} else {
$sql = "SELECT * FROM $track_exercises te "
. "INNER JOIN c_quiz cq ON cq.id = te.exe_exo_id "
. "INNER JOIN course c ON te.exe_cours_id = c.code AND c.id = cq.c_id "
. "WHERE "
. "c.id = %s AND "
. "cq.id IN (%s) "
. "ORDER BY cq.id ";
$sql = sprintf($sql, $courseId, $ids);
}
$sql = sprintf($sql, $courseId, $sessionId, $ids);
$result = Database::query($sql);
$rows = array();
while($row = Database::fetch_array($result, 'ASSOC')) {
$rows[] = $row;
}
return $rows;
}
}

@ -1482,6 +1482,7 @@ function convert_score($score, $weight) {
* @param int 0 = only inactive exercises
* 1 = only active exercises,
* 2 = all exercises
* 3 = active <> -1
* @return array array with exercise data
*/
function get_all_exercises($course_info = null, $session_id = 0, $check_publication_dates = false, $search_exercise = '', $search_all_sessions = false, $active = 2) {
@ -1511,7 +1512,9 @@ function get_all_exercises($course_info = null, $session_id = 0, $check_publicat
//Show courses by active status
$active_sql = '';
if ($active != 2) {
if ($active == 3) {
$active_sql = ' active <> -1 AND';
} else if ($active != 2) {
$active_sql = sprintf(' active = %d AND', $active);
}
@ -1529,13 +1532,18 @@ function get_all_exercises($course_info = null, $session_id = 0, $check_publicat
}
/**
* Get exercise information by id
* @param int Exercise Id
* @return array Exercise info
* @param int $exerciseId Exercise Id
* @param int $courseId The course ID (necessary as c_quiz.id is not unique)
* @return array Exercise info
*/
function get_exercise_by_id($exerciseId = 0)
{
function get_exercise_by_id($exerciseId = 0, $courseId = null) {
$TBL_EXERCICES = Database :: get_course_table(TABLE_QUIZ_TEST);
$conditions = array('where' => array('id = ?' => array($exerciseId)));
if (empty($courseId)) {
$courseId = api_get_course_int_id();
} else {
$courseId = intval($courseId);
}
$conditions = array('where' => array('id = ?' => array($exerciseId), ' AND c_id = ? ' => $courseId));
return Database::select('*', $TBL_EXERCICES, $conditions);
}
/**

@ -166,7 +166,7 @@ if (!empty($track_exercise_info)) {
// if the results_disabled of the Quiz is 1 when block the script
$result_disabled = $track_exercise_info['results_disabled'];
if (!(api_is_platform_admin() || api_is_course_admin()) ) {
if (!(api_is_platform_admin() || api_is_course_admin() || api_is_course_coach()) ) {
if ($result_disabled == 1) {
//api_not_allowed();
$show_results = false;

@ -54,38 +54,46 @@ switch ($action) {
break;
case 'search_course':
if (api_is_platform_admin()) {
$courseList = Coursemanager::get_courses_list(
0,
10,
1, //$orderby = 1,
'ASC',
-1,
$_REQUEST['q'],
null,
true
);
if (!empty($_GET['session_id']) && intval($_GET['session_id'])) {
//if session is defined, lets find only courses of this session
$courseList = SessionManager::get_course_list_by_session_id(
intval($_GET['session_id']),
$_GET['q']
);
} else {
//if session is not defined lets search all courses STARTING with $_GET['q']
//TODO change this function to search not only courses STARTING with $_GET['q']
$courseList = Coursemanager::get_courses_list(
0, //offset
0, //howMany
1, //$orderby = 1
'ASC',
-1, //visibility
$_GET['q'],
null, //$urlId
true //AlsoSearchCode
);
}
$results = array();
require_once api_get_path(LIBRARY_PATH).'course_category.lib.php';
foreach ($courseList as $courseInfo) {
$title = $courseInfo['title'];
if (!empty($courseList)) {
if (!empty($courseInfo['category_code'])) {
$parents = getParentsToString($courseInfo['category_code']);
$title = $parents.$courseInfo['title'];
}
foreach ($courseList as $courseInfo) {
$title = $courseInfo['title'];
$results[] = array(
'id' => $courseInfo['id'],
'text' => $title
);
}
if (!empty($courseInfo['category_code'])) {
$parents = getParentsToString($courseInfo['category_code']);
$title = $parents.$courseInfo['title'];
}
if (!empty($results)) {
/*foreach ($results as &$item) {
$item['id'] = $item['code'];
}*/
$results[] = array(
'id' => $courseInfo['id'],
'text' => $title
);
}
echo json_encode($results);
} else {
echo json_encode(array());
@ -118,6 +126,36 @@ switch ($action) {
}
}
break;
case 'search_course_by_session_all':
if (api_is_platform_admin())
{
if ($_GET['session_id'] == 'TODOS' || $_GET['session_id'] == 'T') {
$_GET['session_id'] = '%';
}
$results = SessionManager::get_course_list_by_session_id_like($_GET['session_id'], $_GET['q']);
//$results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%"));
$results2 = array();
if (!empty($results)) {
foreach ($results as $item) {
$item2 = array();
foreach ($item as $id => $internal) {
if ($id == 'id') {
$item2[$id] = $internal;
}
if ($id == 'title') {
$item2['text'] = $internal;
}
}
$results2[] = $item2;
}
echo json_encode($results2);
} else {
echo json_encode(array());
}
}
break;
case 'search_user_by_course':
if (api_is_platform_admin())
{
@ -137,7 +175,7 @@ switch ($action) {
$result = Database::query($sql_query);
while ($user = Database::fetch_assoc($result))
{
$data[] = array('id' => $user['id'], 'text' => $user['username'] );
$data[] = array('id' => $user['id'], 'text' => $user['username'] . ' (' . $user['firstname'] . ' ' . $user['lastname'] . ')');
}
if (!empty($data))
@ -150,24 +188,25 @@ switch ($action) {
}
break;
case 'search_exercise_by_course':
if (api_is_platform_admin())
{
if (api_is_platform_admin()) {
$course = api_get_course_info_by_id($_GET['course_id']);
require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php';
$session_id = (!empty($_GET['session_id'])) ? intval($_GET['session_id']) : 0 ;
$exercises = get_all_exercises($course, $session_id, false, $_GET['q'], true, 2);
$exercises = get_all_exercises($course, $session_id, false, $_GET['q'], true, 3);
foreach ($exercises as $exercise)
{
$data[] = array('id' => $exercise['id'], 'text' => $exercise['title'] );
foreach ($exercises as $exercise) {
//if (api_get_item_visibility($course, 'quiz', $exercise['id'])) {
$data[] = array('id' => $exercise['id'], 'text' => html_entity_decode($exercise['title']) );
//}
}
if (!empty($data))
{
$data[] = array('id' => 'T', 'text' => 'TODOS');
echo json_encode($data);
} else
{
echo json_encode(array());
echo json_encode(array(array('id' => 'T', 'text' => 'TODOS')));
}
}
break;
@ -176,7 +215,7 @@ switch ($action) {
{
$survey = Database :: get_course_table(TABLE_SURVEY);
$sql = "SELECT survey_id as id, title
$sql = "SELECT survey_id as id, title, anonymous
FROM $survey
WHERE c_id = %d
AND session_id = %d
@ -186,7 +225,8 @@ switch ($action) {
$result = Database::query($sql_query);
while ($survey = Database::fetch_assoc($result))
{
$data[] = array('id' => $survey['id'], 'text' => $survey['title'] );
$survey['title'] .= ($survey['anonymous'] == 1) ? ' (' . get_lang('Anonymous') . ')': '';
$data[] = array('id' => $survey['id'], 'text' => strip_tags(html_entity_decode($survey['title'])));
}
if (!empty($data))
{

@ -135,11 +135,15 @@ switch ($action) {
$count = 0;
foreach ($course_list as $item) {
if (isset($course_id) && !empty($course_id)) {
if ($course_id != $item['id']) {
continue;
}
}
// var_dump($course_list);Exit;
// if(!$item['visibility']) {
// echo "xxx";Exit;
// }
// if (isset($course_id) && !empty($course_id)) {
// if ($course_id != $item['id']) {
// continue;
// }
// }
$list = new LearnpathList(api_get_user_id(), $item['code'], $session_id);
$flat_list = $list->get_flat_list();
$lps[$item['code']] = $flat_list;

@ -0,0 +1,30 @@
<?php
/* For licensing terms, see /license.txt */
$language_file = array('admin', 'registration', 'userInfo');
require_once '../global.inc.php';
$action = $_GET['a'];
switch ($action) {
case 'get_second_select_options':
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$field_id = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
$option_value_id = isset($_REQUEST['option_value_id']) ? $_REQUEST['option_value_id'] : null;
if (!empty($type) && !empty($field_id) && !empty($option_value_id)) {
$field_options = new ExtraFieldOption($type);
echo $field_options->get_second_select_field_options_by_field($field_id, $option_value_id, true);
}
break;
case 'search_tags':
$type = isset($_REQUEST['type']) ? $_REQUEST['type'] : null;
$fieldId = isset($_REQUEST['field_id']) ? $_REQUEST['field_id'] : null;
$tag = isset($_REQUEST['tag']) ? $_REQUEST['tag'] : null;
$extraFieldOption = new ExtraFieldOption($type);
echo $extraFieldOption->getSearchOptionsByField($tag, $fieldId, 10, 'json');
break;
default:
exit;
break;
}
exit;

@ -316,6 +316,7 @@ switch ($action) {
break;
case 'get_sessions':
$courseId = isset($_GET['course_id']) && !empty($_GET['course_id']) ? intval($_GET['course_id']) : null;
$where_condition = str_replace('category_name', 'sc.name', $where_condition);
if (!empty($courseId)) {
$whereCondition .= " AND c.id = $courseId";
}
@ -324,26 +325,33 @@ switch ($action) {
case 'get_session_lp_progress':
case 'get_session_progress':
//@TODO replace this for a more efficient function (not retrieving the whole data)
$course = api_get_course_info_by_id($courseId);
$users = CourseManager::get_student_list_from_course_code($course['code'], true, intval($_GET['session_id']));
$course = api_get_course_info_by_id($_GET['course_id']);
$users = CourseManager::get_student_list_from_course_code($course['code'], true, $_GET['session_id'], $_GET['date_from'], $_GET['date_to']);
$count = count($users);
break;
case 'get_exercise_progress':
//@TODO replace this for a more efficient function (not retrieving the whole data)
$records = SessionManager::get_exercise_progress(intval($_GET['session_id']), intval($_GET['course_id']), intval($_GET['exercise_id']));
$records = Tracking::get_exercise_progress($_GET['session_id'], $_GET['course_id'], $_GET['exercise_id'], $_GET['date_from'], $_GET['date_to']);
$count = count($records);
break;
case 'get_session_access_overview':
//@TODO replace this for a more efficient function (not retrieving the whole data)
$records = SessionManager::get_user_data_access_tracking_overview($_GET['session_id'], $_GET['course_id'], $_GET['student_id'], $_GET['profile'], $_GET['date_to'], $_GET['date_from'], $options);
$records = SessionManager::get_user_data_access_tracking_overview($_GET['session_id'], $_GET['course_id'], $_GET['student_id'], $_GET['profile'], $_GET['date_from'], $_GET['date_to'], $options);
$count = count($records);
break;
case 'get_survey_overview':
//@TODO replace this for a more efficient function (not retrieving the whole data)
$records = SessionManager::get_survey_overview(intval($_GET['session_id']), intval($_GET['course_id']), intval($_GET['survey_id']), $options);
$records = SessionManager::get_survey_overview($_GET['session_id'], $_GET['course_id'], $_GET['survey_id'], $_GET['date_from'], $_GET['date_to'], $options);
$count = count($records);
break;
/*case 'get_extra_fields':
case 'get_exercise_grade':
//@TODO replace this for a more efficient function (not retrieving the whole data)
$course = api_get_course_info_by_id($_GET['course_id']);
$users = CourseManager::get_student_list_from_course_code($course['code'], true, $_GET['session_id']);
$count = count($users);
break;
case 'get_extra_fields':
$type = $_REQUEST['type'];
$obj = new ExtraField($type);
$count = $obj->get_count();
@ -353,7 +361,7 @@ switch ($action) {
$field_id = $_REQUEST['field_id'];
$obj = new ExtraFieldOption($type);
$count = $obj->get_count_by_field_id($field_id);
break;*/
break;
case 'get_timelines':
require_once $libpath.'timeline.lib.php';
$obj = new Timeline();
@ -720,6 +728,9 @@ switch ($action) {
'name', 'nbr_courses', 'nbr_users', 'category_name', 'date_start','date_end', 'coach_name', 'session_active', 'visibility'
);
//Rename Category_name
$where_condition = str_replace('category_name', 'sc.name', $where_condition);
$result = SessionManager::get_sessions_admin(
array(
'where' => $whereCondition,
@ -729,14 +740,11 @@ switch ($action) {
);
break;
case 'get_exercise_progress':
$sessionId = 0;
if (!empty($_GET['course_id']) && !empty($_GET['exercise_id']))
{
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
$exerciseId = intval($_GET['exercise_id']);
$answer = intval($_GET['answer']);
}
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
$exerciseId = intval($_GET['exercise_id']);
$date_from = $_GET['date_from'];
$date_to = $_GET['date_to'];
$columns = array(
'session',
@ -748,11 +756,12 @@ switch ($action) {
'time',
'question_id',
'question',
'description',
'answer',
'correct'
'correct',
);
$result = SessionManager::get_exercise_progress($sessionId, $courseId, $exerciseId, $answer,
$result = Tracking::get_exercise_progress($sessionId, $courseId, $exerciseId, $date_from, $date_to,
array(
'where' => $whereCondition,
'order' => "$sidx $sord",
@ -767,6 +776,7 @@ switch ($action) {
$courseId = intval($_GET['course_id']);
$course = api_get_course_info_by_id($courseId);
}
/**
* Add lessons of course
*
@ -784,7 +794,7 @@ switch ($action) {
}
$columns[] = 'total';
$result = SessionManager::get_session_lp_progress($sessionId, $courseId,
$result = SessionManager::get_session_lp_progress($sessionId, $courseId, $date_from, $date_to,
array(
'where' => $whereCondition,
'order' => "$sidx $sord",
@ -801,6 +811,8 @@ switch ($action) {
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
$surveyId = intval($_GET['survey_id']);
$date_from = $_GET['date_from'];
$date_to = $_GET['date_to'];
//$course = api_get_course_info_by_id($courseId);
}
/**
@ -819,7 +831,7 @@ switch ($action) {
$columns[] = $question_id;
}
$result = SessionManager::get_survey_overview($sessionId, $courseId, $surveyId,
$result = SessionManager::get_survey_overview($sessionId, $courseId, $surveyId, $date_from, $date_to,
array(
'where' => $whereCondition,
'order' => "$sidx $sord",
@ -841,7 +853,7 @@ switch ($action) {
'homeworks',
'wikis',
'surveys',
//course description
//exercises
'course_description_progress',
//exercises
'lessons_total' ,
@ -878,7 +890,7 @@ switch ($action) {
$sessionId = 0;
if (!empty($_GET['course_id']) && !empty($_GET['session_id'])) {
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
$courseId = intval($_GET['course_id']);
}
$result = SessionManager::get_session_progress($sessionId, $courseId,
array(
@ -897,6 +909,7 @@ switch ($action) {
'clicks',
'ip',
'timeLoggedIn',
'session'
);
$sessionId = 0;
if (!empty($_GET['course_id']) && !empty($_GET['session_id'])) {
@ -1074,6 +1087,95 @@ switch ($action) {
$result = $new_result;
}
break;
case 'get_exercise_grade':
$objExercise = new Exercise();
$exercises = $objExercise->getExercisesByCouseSession($_GET['course_id'], $_GET['session_id']);
$cntExer = 4;
if (!empty($exercises)) {
$cntExer += count($exercises);
}
$columns = array();
//Get dynamic column names
$i = 1;
$column_names = array();
foreach (range(1, $cntExer) as $cnt) {
switch ($cnt) {
case 1:
$columns[] = 'session';
$column_names[] = get_lang('Section');
break;
case 2:
$columns[] = 'username';
$column_names[] = get_lang('Username');
break;
case 3:
$columns[] = 'name';
$column_names[] = get_lang('Name');
break;
case $cntExer:
$columns[] = 'finalScore';
$column_names[] = get_lang('FinalScore');
break;
default:
$title = "";
if (!empty($exercises[$cnt - 4]['title'])) {
$title = ucwords(strtolower(trim($exercises[$cnt - 4]['title'])));
}
$columns[] = 'exer' . $i;
$column_names[] = $title;
$i++;
break;
}
}
$quizIds = array();
if (!empty($exercises)) {
foreach($exercises as $exercise) {
$quizIds[] = $exercise['id'];
}
}
$course = api_get_course_info_by_id($_GET['course_id']);
$listUserSess = CourseManager::get_student_list_from_course_code($course['code'], true, $_GET['session_id']);
$usersId = array_keys($listUserSess);
$users = UserManager::get_user_list_by_ids($usersId, null, "lastname, firstname", "$start , $limit");
$exeResults = $objExercise->getExerciseAndResult($_GET['course_id'], $_GET['session_id'], $quizIds);
$arrGrade = array();
foreach ($exeResults as $exeResult) {
$arrGrade[$exeResult['exe_user_id']][$exeResult['exe_exo_id']] = $exeResult['exe_result'];
}
$result = array();
$i = 0;
foreach ($users as $user) {
$sessionInfo = SessionManager::fetch($listUserSess[$user['user_id']]['id_session']);
$result[$i]['session'] = $sessionInfo['name'];
$result[$i]['username'] = $user['username'];
$result[$i]['name'] = $user['lastname'] . " " . $user['firstname'];
$j = 1;
$finalScore = 0;
foreach ($quizIds as $quizID) {
$grade = "";
if (!empty($arrGrade [$user['user_id']][$quizID]) || $arrGrade [$user['user_id']][$quizID] == 0) {
$finalScore += $grade = $arrGrade [$user['user_id']][$quizID];
}
$result[$i]['exer' . $j] = $grade;
$j++;
}
if ($finalScore > 20) {
$finalScore = 20;
}
$result[$i]['finalScore'] = number_format($finalScore, 2);
$i++;
}
break;
case 'get_extra_field_options':
$obj = new ExtraFieldOption($type);
$columns = array('option_display_text', 'option_value', 'option_order');
@ -1146,11 +1248,12 @@ $allowed_actions = array(
'get_grade_models',
'get_event_email_template',
'get_user_skill_ranking',
//'get_extra_fields',
//'get_extra_field_options',
'get_extra_fields',
'get_extra_field_options',
//'get_course_exercise_medias',
'get_user_course_report',
'get_user_course_report_resumed'
'get_user_course_report_resumed',
'get_exercise_grade'
);
//5. Creating an obj to return a json
@ -1183,7 +1286,13 @@ if (in_array($action, $allowed_actions)) {
case 'xls':
//TODO add date if exists
$file_name = (!empty($action)) ? $action : 'company_report';
Export::export_table_xls($array, $file_name);
require_once api_get_path(LIBRARY_PATH).'browser/Browser.php';
$browser = new Browser();
if ($browser->getPlatform() == Browser::PLATFORM_WINDOWS) {
Export::export_table_xls_html($array, $file_name, 'ISO-8859-15');
} else {
Export::export_table_xls_html($array, $file_name);
}
break;
case 'csv':
default:
@ -1199,7 +1308,6 @@ if (in_array($action, $allowed_actions)) {
if (!empty($result)) {
foreach ($result as $row) {
//print_r($row);
// if results tab give not id, set id to $i otherwise id="null" for all <tr> of the jqgrid - ref #4235
if (!isset($row['id']) || isset($row['id']) && $row['id'] == '') {
$response->rows[$i]['id']= $i;

@ -47,9 +47,33 @@ switch ($action) {
}
}
break;
case 'search_session_all':
if (api_is_platform_admin()) {
$results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%", 'c.id ='=>$_REQUEST['course_id']));
$results2 = array();
if (!empty($results)) {
foreach ($results as $item) {
$item2 = array();
foreach ($item as $id => $internal) {
if ($id == 'id') {
$item2[$id] = $internal;
}
if ($id == 'name') {
$item2['text'] = $internal;
}
}
$results2[] = $item2;
}
$results2[] = array('T', 'text' => 'TODOS', 'id' => 'T');
echo json_encode($results2);
} else {
echo json_encode(array(array('T', 'text' => 'TODOS', 'id' => 'T')));
}
}
break;
case 'search_session_by_course':
if (api_is_platform_admin()) {
$results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%"));
$results = SessionManager::get_sessions_list(array('s.name LIKE' => "%".$_REQUEST['q']."%", 'c.id ='=>$_REQUEST['course_id']));
$results2 = array();
if (!empty($results)) {
foreach ($results as $item) {
@ -64,9 +88,10 @@ switch ($action) {
}
$results2[] = $item2;
}
$results2[] = array('T', 'text' => 'TODOS', 'id' => 'T');
echo json_encode($results2);
} else {
echo json_encode(array());
echo json_encode(array(array('T', 'text' => 'TODOS', 'id' => 'T')));
}
}
break;

@ -50,7 +50,7 @@ $TechnicalIssuesDescription = 'This portal is currently experiencing technical i
if (is_int($global_error_code) && $global_error_code > 0) {
$theme = 'chamilo/';
$theme = 'chamilo_red_utp/';
$css_path = 'main/css/';
$css_file = $css_path.$theme.'default.css';
$bootstrap_file = $css_path.'bootstrap.css';

@ -280,3 +280,9 @@ if ($intro_dispCommand) {
}
}
$introduction_section .= '</div>';
$browser = api_get_navigator();
if (strpos($introduction_section, '<iframe') !== false && $browser['name'] == 'Chrome') {
header("X-XSS-Protection: 0");
}

@ -917,6 +917,11 @@ class Autoload
$result['UserForm'] = '/main/gradebook/lib/fe/userform.class.php';
$result['UserGroup'] = '/main/inc/lib/usergroup.lib.php';
$result['UserManager'] = '/main/inc/lib/usermanager.lib.php';
$result['ExtraField'] = '/main/inc/lib/extra_field.lib.php';
$result['ExtraFieldOption'] = '/main/inc/lib/extra_field_option.lib.php';
$result['ExtraFieldValue'] = '/main/inc/lib/extra_field_value.lib.php';
$result['UserTable'] = '/main/gradebook/lib/fe/usertable.class.php';
$result['Utf8'] = '/main/inc/lib/system/text/utf8.class.php';
$result['Utf8Decoder'] = '/main/inc/lib/system/text/utf8_decoder.class.php';

@ -1617,13 +1617,16 @@ class CourseManager
* This only returns the users that are registered in this actual course, not linked courses.
*
* @param string $course_code
* @param boolean $full list to true if we want sessions students too
* @param boolean $with_session
* @param integer $session_id
* @param date $date_from
* @param date $date_to
* @return array with user id
*/
public static function get_student_list_from_course_code($course_code, $with_session = false, $session_id = 0) {
public static function get_student_list_from_course_code($course_code, $with_session = false, $session_id = 0, $date_from = null, $date_to = null) {
$session_id = intval($session_id);
$course_code = Database::escape_string($course_code);
$students = array();
if ($session_id == 0) {
@ -1639,11 +1642,27 @@ class CourseManager
// students subscribed to the course through a session
if ($with_session) {
$sql_query = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)."
WHERE course_code = '$course_code' AND status <> 2";
$joinSession = "";
//Session creation date
if (!empty($date_from) && !empty($date_to)) {
$joinSession = "INNER JOIN " . Database::get_main_table(TABLE_MAIN_SESSION) . " s";
}
$sql_query = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)." scu
$joinSession
WHERE scu.course_code = '$course_code' AND scu.status <> 2";
if (!empty($date_from) && !empty($date_to)) {
$date_from = Database::escape_string($date_from);
$date_to = Database::escape_string($date_to);
$sql_query .= " AND s.date_start >= '$date_from' AND s.date_end <= '$date_to'";
}
if ($session_id != 0) {
$sql_query .= ' AND id_session = '.$session_id;
$sql_query .= ' AND scu.id_session = '.$session_id;
}
$rs = Database::query($sql_query);
while($student = Database::fetch_array($rs)) {
$students[$student['id_user']] = $student;

@ -62,6 +62,10 @@ define('TABLE_MAIN_USER_FIELD', 'user_field');
define('TABLE_MAIN_USER_FIELD_OPTIONS', 'user_field_options');
define('TABLE_MAIN_USER_FIELD_VALUES', 'user_field_values');
define('TABLE_MAIN_LP_FIELD', 'lp_field');
define('TABLE_MAIN_LP_FIELD_OPTIONS', 'lp_field_options');
define('TABLE_MAIN_LP_FIELD_VALUES', 'lp_field_values');
//User tags
define('TABLE_MAIN_TAG', 'tag');
define('TABLE_MAIN_USER_REL_TAG', 'user_rel_tag');

@ -95,9 +95,6 @@ class Display
if (!empty($page_header)) {
self::$global_template->assign('header', $page_header);
}
self::$global_template->assign('course_code', api_get_course_id());
echo self::$global_template->show_header_template();
}
@ -935,15 +932,17 @@ class Display
* This function need to be in the ready jquery function example --> $(function() { <?php echo Display::grid_js('grid' ...); ?> }
* In order to work this function needs the Display::grid_html function with the same div id
*
* @param string div id
* @param string url where the jqgrid will ask for data (if datatype = json)
* @param array Visible columns (you should use get_lang). An array in which we place the names of the columns.
* @param string $div_id div id
* @param string $url url where the jqgrid will ask for data (if datatype = json)
* @param array $column_names Visible columns (you should use get_lang). An array in which we place the names of the columns.
* This is the text that appears in the head of the grid (Header layer).
* Example: colname {name:'date', index:'date', width:120, align:'right'},
* @param array the column model : Array which describes the parameters of the columns.This is the most important part of the grid.
* @param array $column_model the column model : Array which describes the parameters of the columns.This is the most important part of the grid.
* For a full description of all valid values see colModel API. See the url above.
* @param array extra parameters
* @param array data that will be loaded
* @param array $extra_params extra parameters
* @param array $data data that will be loaded
* @param string $formatter A string that will be appended to the JSON returned
* @param bool $fixed_width not implemented yet
* @return string the js code
*
*/
@ -955,7 +954,7 @@ class Display
$extra_params,
$data = array(),
$formatter = '',
$width_fix = false
$fixed_width = false
) {
$obj = new stdClass();
$obj->first = 'first';
@ -1022,7 +1021,10 @@ class Display
// Adding extra params
if (!empty($extra_params)) {
foreach ($extra_params as $key => $element) {
$obj->$key = $element;
// the groupHeaders key gets a special treatment
if ($key != 'groupHeaders') {
$obj->$key = $element;
}
}
}
@ -1040,7 +1042,8 @@ class Display
$json_encode = json_encode($obj);
if (!empty($data)) {
//Converts the "data":"js_variable" to "data":js_variable othersiwe it will not work
//Converts the "data":"js_variable" to "data":js_variable,
// otherwise it will not work
$json_encode = str_replace('"data":"'.$data_var.'"', '"data":'.$data_var.'', $json_encode);
}
@ -1055,9 +1058,27 @@ class Display
// Creating the jqgrid element.
$json .= '$("#'.$div_id.'").jqGrid({';
//$json .= $beforeSelectRow;
$json .= $json_encode;
$json .= '});';
//Grouping headers option
if (isset($extra_params['groupHeaders'])) {
$groups = '';
foreach ($extra_params['groupHeaders'] as $group) {
//{ "startColumnName" : "courses", "numberOfColumns" : 1, "titleText" : "Order Info" },
$groups .= '{ "startColumnName" : "' . $group['startColumnName'] . '", "numberOfColumns" : ' . $group['numberOfColumns'] . ', "titleText" : "' . $group['titleText'] . '" },';
}
$json .= '$("#'.$div_id.'").jqGrid("setGroupHeaders", {
"useColSpanStyle" : false,
"groupHeaders" : [
' . $groups . '
]
});';
}
$all_text = addslashes(get_lang('All'));
$json .= '$("'.$obj->pager.' option[value='.$all_value.']").text("'.$all_text.'");';
$json.= "\n";

@ -2695,7 +2695,7 @@ class DocumentManager
$session_condition = " AND props.id_session='" . $session_id . "' ";
}
$sql = "SELECT SUM(size) FROM " . $TABLE_ITEMPROPERTY . " AS props, " . $TABLE_DOCUMENT . " AS docs
$sql = "SELECT coalesce(docs.size, 0), docs.path, docs.filetype FROM " . $TABLE_ITEMPROPERTY . " AS props, " . $TABLE_DOCUMENT . " AS docs
WHERE props.c_id = $course_id AND
docs.c_id = $course_id AND
docs.id = props.ref AND
@ -2703,15 +2703,22 @@ class DocumentManager
props.visibility <> 2
$group_condition
$session_condition
ORDER BY docs.id
";
$result = Database::query($sql);
if ($result && Database::num_rows($result) != 0) {
$row = Database::fetch_row($result);
return $row[0];
} else {
return 0;
//Not count the same file more than once
//if there is more than once just take the last
$docsSize = array();
while ($row = Database::fetch_row($result)) {
$md5Key = md5($row[1]);
if (!empty($row[2]) && $row[2] == 'folder') {
$docsSize[$md5Key] = 4096;
} else {
$docsSize[$md5Key] = $row[0];
}
}
return array_sum($docsSize);
}
/**

@ -1472,7 +1472,7 @@ function delete_attempt($exe_id, $user_id, $course_code, $session_id, $question_
* @param int $user_id
* @param string $course_code
* @param int $question_id
* @todo add session_id for 1.10
* @todo add session_id for 10
*/
function delete_attempt_hotspot($exe_id, $user_id, $course_code, $session_id = 0, $question_id) {
$table_track_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_HOTSPOT);
@ -1504,11 +1504,32 @@ function event_course_login($course_code, $user_id, $session_id) {
$course_code = Database::escape_string($course_code);
$user_id = intval($user_id);
$session_id = intval($session_id);
$session_lifetime = 3600;
$sql = "INSERT INTO $course_tracking_table(course_code, user_id, login_course_date, logout_course_date, counter, session_id)
VALUES('".$course_code."', '".$user_id."', '$time', '$time', '1', '".$session_id."')";
Database::query($sql);
//We select the last record for the current course in the course tracking table
$sql = "SELECT course_access_id FROM $course_tracking_table
WHERE user_id = $user_id AND
course_code = '$course_code' AND
session_id = $session_id AND
login_course_date > '$time' - INTERVAL $session_lifetime SECOND
ORDER BY login_course_date DESC LIMIT 0,1";
$result = Database::query($sql);
//error_log(preg_replace('/\s+/',' ',$sql));
if (Database::num_rows($result) > 0) {
$i_course_access_id = Database::result($result,0,0);
//We update the course tracking table
$sql = "UPDATE $course_tracking_table SET logout_course_date = '$time', counter = counter+1
WHERE course_access_id = ".intval($i_course_access_id)." AND session_id = ".$session_id;
Database::query($sql);
//error_log(preg_replace('/\s+/',' ',$sql));
} else {
$sql="INSERT INTO $course_tracking_table (course_code, user_id, login_course_date, logout_course_date, counter, session_id)" .
"VALUES('".$course_code."', '".$user_id."', '$time', '$time', '1','".$session_id."')";
Database::query($sql);
//error_log(preg_replace('/\s+/',' ',$sql));
}
// Course catalog stats modifications see #4191
CourseManager::update_course_ranking(null, null, null, null, true, false);
}

@ -68,7 +68,7 @@ class Export
$file->put($row);
}
$file->close();
DocumentManager::file_send_for_download($path, true, $filename.'.csv');
DocumentManager::file_send_for_download($path, false, $filename.'.csv');
unlink($path);
exit;
}
@ -78,17 +78,50 @@ class Export
* @param array $data
* @param string $filename
*/
public static function export_table_xls($data, $filename = 'export')
public static function export_table_xls($data, $filename = 'export', $encoding = 'utf-8')
{
$file = api_get_path(SYS_ARCHIVE_PATH).uniqid('').'.xls';
$handle = fopen($file, 'a+');
$systemEncoding = api_get_system_encoding();
foreach ($data as $row) {
fwrite($handle, implode("\t", $row)."\n");
$string = implode("\t", $row);
if ($encoding != 'utf-8') {
$string = api_convert_encoding($string, $encoding, $systemEncoding);
}
fwrite($handle, $string."\n");
}
fclose($handle);
DocumentManager::file_send_for_download($file, true, $filename.'.xls');
DocumentManager::file_send_for_download($file, false, $filename.'.xls');
}
/**
* Export tabular data to XLS-file (as html table)
* @param array $data
* @param string $filename
*/
public static function export_table_xls_html($data, $filename = 'export', $encoding = 'utf-8')
{
$file = api_get_path(SYS_ARCHIVE_PATH).uniqid('').'.xls';
$handle = fopen($file, 'a+');
$systemEncoding = api_get_system_encoding();
fwrite($handle, '<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html" charset="utf-8" /><body><table>');
foreach ($data as $id => $row) {
foreach ($row as $id2 => $row2) {
$data[$id][$id2] = api_htmlentities($row2);
}
}
foreach ($data as $row) {
$string = implode("</td><td>", $row);
$string = '<tr><td>' . $string . '</td></tr>';
if ($encoding != 'utf-8') {
$string = api_convert_encoding($string, $encoding, $systemEncoding);
}
fwrite($handle, $string."\n");
}
fwrite($handle, '</table></body></html>');
fclose($handle);
DocumentManager::file_send_for_download($file, false, $filename.'.xls');
}
/**
* Export tabular data to XML-file
* @param array Simple array of data to put in XML

File diff suppressed because it is too large Load Diff

@ -0,0 +1,659 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Declaration of the ExtraFieldOption class
*/
/**
* Handles the extra fields for various objects (users, sessions, courses)
*/
class ExtraFieldOption extends Model
{
public $columns = array(
'id', 'field_id', 'option_value', 'option_display_text', 'option_order', 'priority', 'priority_message', 'tms'
);
/**
* Gets the table for the type of object for which we are using an extra field
* @param string Type of object (course, user or session)
*/
public function __construct($type)
{
$this->type = $type;
switch ($this->type) {
case 'course':
$this->table = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_OPTIONS);
break;
case 'user':
$this->table = Database::get_main_table(TABLE_MAIN_USER_FIELD_OPTIONS);
break;
case 'session':
$this->table = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_OPTIONS);
break;
case 'question':
$this->table = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD_OPTIONS);
break;
case 'lp':
$this->table = Database::get_main_table(TABLE_MAIN_LP_FIELD_OPTIONS);
break;
}
}
/**
* Gets the number of options already available in the table for this item type
* @return int Number of options available
* @assert () >= 0
*/
public function get_count()
{
$row = Database::select('count(*) as count', $this->table, array(), 'first');
return $row['count'];
}
/**
* Gets the number of options available for this field
* @param int Field ID
* @return int Number of options
* @assert ('') === false
* @assert (-1) == 0
* @assert (0) == 0
*/
public function get_count_by_field_id($field_id)
{
if (empty($field_id)) {
return false;
}
$row = Database::select(
'count(*) as count',
$this->table,
array('where' => array('field_id = ?' => $field_id)),
'first'
);
return $row['count'];
}
/**
* Returns a list of options for a specific field, separated by ";"
* @param int Field ID
* @param bool Indicates whether we want the results to be given with their id
* @param string Order by clause (without the "order by") to be added to the SQL query
* @return string List of options separated by ;
* @assert (-1, false, null) == ''
*/
public function get_field_options_to_string($field_id, $add_id_in_array = false, $ordered_by = null)
{
$options = self::get_field_options_by_field($field_id, $add_id_in_array, $ordered_by);
$new_options = array();
if (!empty($options)) {
foreach ($options as $option) {
$new_options[] = $option['option_value'].':'.$option['option_display_text'];
}
$string = implode(';', $new_options);
return $string;
}
return '';
}
/**
* Delete all the options of a specific field
* @param int Field ID
* @result void
* @assert (-1) === false
*/
public function delete_all_options_by_field_id($field_id)
{
$field_id = intval($field_id);
$sql = "DELETE FROM {$this->table} WHERE field_id = $field_id";
$r = Database::query($sql);
return $r;
}
/**
* @param array $params
*
* @return int
*/
public function saveOptions($params, $show_query = false)
{
$optionInfo = self::get_field_option_by_field_and_option($params['field_id'], $params['option_value']);
// Use URLify only for new items
//$optionValue = URLify::filter($params['option_value']);
$optionValue = replace_dangerous_char($params['option_value']);
$option = $params['option_value'];
if ($optionInfo == false) {
$order = self::get_max_order($params['field_id']);
$new_params = array(
'field_id' => $params['field_id'],
'option_value' => trim($optionValue),
'option_display_text' => trim($option),
'option_order' => $order,
'tms' => api_get_utc_datetime(),
);
return parent::save($new_params, $show_query);
}
return false;
}
/**
* Saves an option into the corresponding *_field_options table
* @param array Parameters to be considered for the insertion
* @param bool Whether to show the query (sent to the parent save() method)
* @return bool True on success, false on error
* @assert (array('field_id'=>0), false) === false
* @assert (array('field_id'=>1), false) === true
*/
public function save($params, $show_query = false)
{
$field_id = intval($params['field_id']);
if (empty($field_id)) {
return false;
}
$time = api_get_utc_datetime();
if (!empty($params['field_options']) &&
in_array(
$params['field_type'],
array(
ExtraField::FIELD_TYPE_RADIO,
ExtraField::FIELD_TYPE_SELECT,
ExtraField::FIELD_TYPE_SELECT_MULTIPLE,
ExtraField::FIELD_TYPE_DOUBLE_SELECT
)
)
) {
if ($params['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
//$params['field_options'] = France:Paris;Bretagne;Marseilles;Lyon|Belgique:Bruxelles;Namur;Liège;Bruges|Peru:Lima;Piura;
$options_parsed = ExtraField::extra_field_double_select_convert_string_to_array(
$params['field_options']
);
if (!empty($options_parsed)) {
foreach ($options_parsed as $key => $option) {
$sub_options = $option['options'];
$new_params = array(
'field_id' => $field_id,
'option_value' => 0,
'option_display_text' => $option['label'],
'option_order' => 0,
'tms' => $time,
);
// Looking if option already exists:
$option_info = self::get_field_option_by_field_id_and_option_display_text(
$field_id,
$option['label']
);
if (empty($option_info)) {
$sub_id = parent::save($new_params, $show_query);
} else {
$sub_id = $option_info['id'];
$new_params['id'] = $sub_id;
parent::update($new_params, $show_query);
}
foreach ($sub_options as $sub_option) {
if (!empty($sub_option)) {
$new_params = array(
'field_id' => $field_id,
'option_value' => $sub_id,
'option_display_text' => $sub_option,
'option_order' => 0,
'tms' => $time,
);
$option_info = self::get_field_option_by_field_id_and_option_display_text_and_option_value(
$field_id,
$sub_option,
$sub_id
);
if (empty($option_info)) {
parent::save($new_params, $show_query);
} else {
$new_params['id'] = $option_info['id'];
parent::update($new_params, $show_query);
}
}
}
}
}
$list = array();
} else {
$list = explode(';', $params['field_options']);
}
if (!empty($list)) {
foreach ($list as $option) {
$option_info = self::get_field_option_by_field_and_option($field_id, $option);
// Use URLify only for new items
$optionValue = URLify::filter($option);
$option = trim($option);
if ($option_info == false) {
$order = self::get_max_order($field_id);
$new_params = array(
'field_id' => $field_id,
'option_value' => trim($optionValue),
'option_display_text' => trim($option),
'option_order' => $order,
'tms' => $time,
);
parent::save($new_params, $show_query);
}
}
}
}
return true;
}
/**
* Save one option item at a time
* @param array Parameters specific to the option
* @param bool Whether to show the query (sent to parent save() method)
* @param bool Whether to insert even if the option already exists
* @return bool True on success, false on failure
* @assert (array('field_id'=>0),false) === false
* @assert (array('field_id'=>0),false) === true
*/
public function save_one_item($params, $show_query = false, $insert_repeated = true)
{
$field_id = intval($params['field_id']);
if (empty($field_id)) {
return false;
}
if (isset($params['option_value'])) {
$params['option_value'] = trim($params['option_value']);
}
if (isset($params['option_display_text'])) {
$params['option_display_text'] = trim($params['option_display_text']);
}
$params['tms'] = api_get_utc_datetime();
if (empty($params['option_order'])) {
$order = self::get_max_order($field_id);
$params['option_order'] = $order;
}
if ($insert_repeated) {
parent::save($params, $show_query);
} else {
$check = self::get_field_option_by_field_and_option($field_id, $params['option_value']);
if ($check == false) {
parent::save($params, $show_query);
}
}
return true;
}
/**
* Get the complete row of a specific option of a specific field
* @param int Field ID
* @param string Value of the option
* @return mixed The row on success or false on failure
* @assert (0,'') === false
*/
public function get_field_option_by_field_and_option($field_id, $option_value)
{
$field_id = intval($field_id);
$option_value = Database::escape_string($option_value);
$sql = "SELECT * FROM {$this->table}
WHERE field_id = $field_id AND option_value = '".$option_value."'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
return Database::store_result($result, 'ASSOC');
}
return false;
}
/**
* Get the complete row of a specific option's display text of a specific field
* @param int Field ID
* @param string Display value of the option
* @return mixed The row on success or false on failure
* @assert (0, '') === false
*/
public function get_field_option_by_field_id_and_option_display_text($field_id, $option_display_text)
{
$field_id = intval($field_id);
$option_display_text = Database::escape_string($option_display_text);
$sql = "SELECT * FROM {$this->table}
WHERE field_id = $field_id AND option_display_text = '".$option_display_text."'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
return Database::fetch_array($result, 'ASSOC');
}
return false;
}
/**
* Get the complete row of a specific option's display text of a specific field
* @param int Field ID
* @param string Display value of the option
* @param string Value of the option
* @return mixed The row on success or false on failure
* @assert (0, '', '') === false
*/
public function get_field_option_by_field_id_and_option_display_text_and_option_value(
$field_id,
$option_display_text,
$option_value
) {
$field_id = intval($field_id);
$option_display_text = Database::escape_string($option_display_text);
$option_value = Database::escape_string($option_value);
$sql = "SELECT * FROM {$this->table}
WHERE
field_id = $field_id AND
option_display_text = '".$option_display_text."' AND
option_value = '$option_value'";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
return Database::fetch_array($result, 'ASSOC');
}
return false;
}
/**
* Gets an array of options for a specific field
* @param int The field ID
* @param bool Whether to add the row ID in the result
* @param string Extra ordering query bit
* @result mixed Row on success, false on failure
* @assert (0, '') === false
*/
public function get_field_options_by_field($field_id, $add_id_in_array = false, $ordered_by = null)
{
$field_id = intval($field_id);
$sql = "SELECT * FROM {$this->table} WHERE field_id = $field_id ";
if (!empty($ordered_by)) {
$sql .= " ORDER BY $ordered_by ";
}
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
if ($add_id_in_array) {
$options = array();
while ($row = Database::fetch_array($result, 'ASSOC')) {
$options[$row['id']] = $row;
}
return $options;
} else {
return Database::store_result($result, 'ASSOC');
}
}
return false;
}
/**
* Get options for a specific field as array or in JSON format suited for the double-select format
* @param int Field ID
* @param int Option value ID
* @param bool Return format (whether it should be formatted to JSON or not)
* @return mixed Row/JSON on success
*/
public function get_second_select_field_options_by_field($field_id, $option_value_id, $to_json = false)
{
$field_id = intval($field_id);
$option_value_id = intval($option_value_id);
$options = array();
$sql = "SELECT * FROM {$this->table}
WHERE field_id = $field_id AND option_value = $option_value_id
ORDER BY option_display_text";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
$options = Database::store_result($result, 'ASSOC');
}
if ($to_json) {
$string = null;
if (!empty($options)) {
$array = array();
foreach ($options as $option) {
$array[$option['id']] = $option['option_display_text'];
}
$string = json_encode($array);
}
return $string;
}
return $options;
}
/**
* Get options for a specific field as string split by ;
* @param int Field ID
* @param string Extra query bit for reordering
* @return string HTML string of options
* @assert (0, '') === null
*/
public function get_field_options_by_field_to_string($field_id, $ordered_by = null)
{
$field = new ExtraField($this->type);
$field_info = $field->get($field_id);
$options = self::get_field_options_by_field($field_id, false, $ordered_by);
$elements = array();
if (!empty($options)) {
switch ($field_info['field_type']) {
case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
$html = ExtraField::extra_field_double_select_convert_array_to_string($options);
break;
default:
foreach ($options as $option) {
$elements[] = $option['option_value'];
}
$html = implode(';', $elements);
break;
}
return $html;
}
return null;
}
/**
* Get the maximum order value for a specific field
* @param int Field ID
* @return int Current max ID + 1 (we start from 0)
* @assert (0, '') === 1
*/
public function get_max_order($field_id)
{
$field_id = intval($field_id);
$sql = "SELECT MAX(option_order) FROM {$this->table} WHERE field_id = $field_id";
$res = Database::query($sql);
$max = 1;
if (Database::num_rows($res) > 0) {
$row = Database::fetch_array($res);
$max = $row[0] + 1;
}
return $max;
}
/**
* Update the option using the given params
* @param array $params data to be saved
*/
public function update($params)
{
parent::update($params);
}
/**
* Display a form with the options for the field_id given in REQUEST
* @return void Prints output
*/
function display()
{
// action links
echo '<div class="actions">';
//echo '<a href="../admin/index.php">'.Display::return_icon('back.png', get_lang('BackTo').' '.get_lang('PlatformAdmin'),'', ICON_SIZE_MEDIUM).'</a>';
$field_id = isset($_REQUEST['field_id']) ? intval($_REQUEST['field_id']) : null;
echo '<a href="'.api_get_self(
).'?action=add&type='.$this->type.'&field_id='.$field_id.'">'.Display::return_icon(
'add_user_fields.png',
get_lang('Add'),
'',
ICON_SIZE_MEDIUM
).'</a>';
echo '</div>';
echo Display::grid_html('extra_field_options');
}
public function getPriorityOptions()
{
return array(
'' => get_lang('SelectAnOption'),
1 => get_lang('Success'),
2 => get_lang('Info'),
3 => get_lang('Warning'),
4 => get_lang('Error'),
);
}
public function getPriorityMessageType($priority)
{
switch ($priority) {
case 1:
return 'success';
case 2:
return 'info';
case 3:
return 'warning';
case 4:
return 'error';
}
return null;
}
/**
* Returns an HTML form for the current field
* @param string URL to send the form to (action=...)
* @param string Type of action to offer through the form (edit, usually)
* @return string HTML form
*/
public function return_form($url, $action)
{
$form_name = $this->type.'_field';
$form = new FormValidator($form_name, 'post', $url);
// Settting the form elements
$header = get_lang('Add');
if ($action == 'edit') {
$header = get_lang('Modify');
}
$form->addElement('header', $header);
$id = isset($_GET['id']) ? intval($_GET['id']) : '';
$form->addElement('hidden', 'id', $id);
$form->addElement('hidden', 'type', $this->type);
$form->addElement('hidden', 'field_id', $this->field_id);
$form->addElement('text', 'option_display_text', get_lang('Name'), array('class' => 'span5'));
$form->addElement('text', 'option_value', get_lang('Value'), array('class' => 'span5'));
$form->addElement('text', 'option_order', get_lang('Order'), array('class' => 'span2'));
$form->addElement('select', 'priority', get_lang('Priority'), $this->getPriorityOptions());
$form->addElement('textarea', 'priority_message', get_lang('PriorityMessage'));
$defaults = array();
if ($action == 'edit') {
// Setting the defaults
$defaults = $this->get($id);
$form->freeze('option_value');
$form->addElement('button', 'submit', get_lang('Modify'), 'class="save"');
} else {
$form->addElement('button', 'submit', get_lang('Add'), 'class="save"');
}
$form->setDefaults($defaults);
// Setting the rules
$form->addRule('option_display_text', get_lang('ThisFieldIsRequired'), 'required');
//$form->addRule('field_variable', get_lang('ThisFieldIsRequired'), 'required');
$form->addRule('option_value', get_lang('ThisFieldIsRequired'), 'required');
return $form;
}
/**
* @param string $tag
* @param int $field_id
* @param int $limit
* @return array
*/
public function searchByField($tag, $field_id, $limit = 10)
{
$field_id = intval($field_id);
$limit = intval($limit);
$tag = Database::escape_string($tag);
$sql = "SELECT DISTINCT id, option_display_text
FROM {$this->table}
WHERE
field_id = '".$field_id."' AND
option_value LIKE '%$tag%'
ORDER BY option_value
LIMIT 0, $limit
";
$result = Database::query($sql);
$values = array();
if (Database::num_rows($result)) {
$values = Database::store_result($result, 'ASSOC');
}
return $values;
}
/**
* @param string $tag
* @param int $field_id
* @param int $limit
*
* @return string
*/
public function getSearchOptionsByField($tag, $field_id, $limit = 10)
{
$result = $this->searchByField($tag, $field_id, $limit = 10);
$values = array();
$json = null;
if (!empty($result)) {
foreach ($result as $item) {
$values[] = array(
'value' => $item['id'],
'caption' => $item['option_display_text'],
);
}
$json = json_encode($values);
}
return $json;
}
}

@ -0,0 +1,654 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Declaration for the ExtraFieldValue class, managing the values in extra
* fields for any datatype
* @package chamilo.library
*/
/**
* Class managing the values in extra fields for any datatype
* @package chamilo.library.extrafields
*/
class ExtraFieldValue extends Model
{
public $type = null;
public $columns = array('id', 'field_id', 'field_value', 'tms', 'comment');
/** @var string session_id, course_code, user_id, question id */
public $handler_id = null;
public $entityName;
/**
* Formats the necessary elements for the given datatype
* @param string The type of data to which this extra field applies (user, course, session, ...)
* @return void (or false if unmanaged datatype)
* @assert (-1) === false
*/
public function __construct($type)
{
$this->type = $type;
$extra_field = new ExtraField($this->type);
$this->handler_id = $extra_field->handler_id;
switch ($this->type) {
case 'course':
$this->table = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
$this->table_handler_field = Database::get_main_table(TABLE_MAIN_COURSE_FIELD);
$this->author_id = 'user_id';
$this->entityName = 'ChamiloLMS\Entity\CourseFieldValues';
break;
case 'user':
$this->table = Database::get_main_table(TABLE_MAIN_USER_FIELD_VALUES);
$this->table_handler_field = Database::get_main_table(TABLE_MAIN_USER_FIELD);
$this->author_id = 'author_id';
$this->entityName = 'ChamiloLMS\Entity\UserFieldValues';
break;
case 'session':
$this->table = Database::get_main_table(TABLE_MAIN_SESSION_FIELD_VALUES);
$this->table_handler_field = Database::get_main_table(TABLE_MAIN_SESSION_FIELD);
$this->author_id = 'user_id';
$this->entityName = 'ChamiloLMS\Entity\SessionFieldValues';
break;
case 'question':
$this->table = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD_VALUES);
$this->table_handler_field = Database::get_main_table(TABLE_MAIN_QUESTION_FIELD);
$this->author_id = 'user_id';
$this->entityName = 'ChamiloLMS\Entity\QuestionFieldValues';
break;
case 'lp':
$this->table = Database::get_main_table(TABLE_MAIN_LP_FIELD_VALUES);
$this->table_handler_field = Database::get_main_table(TABLE_MAIN_LP_FIELD);
$this->author_id = 'lp_id';
//$this->entityName = 'ChamiloLMS\Entity\QuestionFieldValues';
break;
default:
//unmanaged datatype, return false to let the caller know it
// didn't work
return false;
}
$this->columns[] = $this->handler_id;
$this->columns[] = $this->author_id;
}
/**
* Gets the number of values stored in the table (all fields together)
* for this type of resource
* @return integer Number of rows in the table
* @assert () !== false
*/
public function get_count()
{
$row = Database::select('count(*) as count', $this->table, array(), 'first');
return $row['count'];
}
/**
* Saves a series of records given as parameter into the coresponding table
* @param array Structured parameter for the insertion into the *_field_values table
* @return mixed false on empty params, void otherwise
* @assert (array()) === false
*/
public function save_field_values($params)
{
$extra_field = new ExtraField($this->type);
if (empty($params[$this->handler_id])) {
return false;
}
foreach ($params as $key => $value) {
$found = strpos($key, '__persist__');
if ($found) {
$tempKey = str_replace('__persist__', '', $key);
if (!isset($params[$tempKey])) {
$params[$tempKey] = array();
}
break;
}
}
// Parse params.
foreach ($params as $key => $value) {
if (substr($key, 0, 6) == 'extra_') {
// An extra field.
$field_variable = substr($key, 6);
$extra_field_info = $extra_field->get_handler_field_info_by_field_variable($field_variable);
if ($extra_field_info) {
$commentVariable = 'extra_'.$field_variable.'_comment';
$comment = isset($params[$commentVariable]) ? $params[$commentVariable] : null;
switch ($extra_field_info['field_type']) {
case ExtraField::FIELD_TYPE_TAG :
$old = self::getAllValuesByItemAndField(
$extra_field_info['id'],
$params[$this->handler_id]
);
$deleteItems = array();
if (!empty($old)) {
$oldIds = array();
foreach ($old as $oldItem) {
$oldIds[] = $oldItem['field_value'];
}
$deleteItems = array_diff($oldIds, $value);
}
foreach ($value as $optionId) {
$new_params = array(
$this->handler_id => $params[$this->handler_id],
'field_id' => $extra_field_info['id'],
'field_value' => $optionId,
'comment' => $comment
);
self::save($new_params);
}
if (!empty($deleteItems)) {
foreach ($deleteItems as $deleteFieldValue) {
self::deleteValuesByHandlerAndFieldAndValue(
$extra_field_info['id'],
$params[$this->handler_id],
$deleteFieldValue
);
}
}
break;
default;
$new_params = array(
$this->handler_id => $params[$this->handler_id],
'field_id' => $extra_field_info['id'],
'field_value' => $value,
'comment' => $comment
);
self::save($new_params);
}
}
}
}
}
/**
* Save values in the *_field_values table
* @param array Structured array with the values to save
* @param boolean Whether to show the insert query (passed to the parent save() method)
* @result mixed The result sent from the parent method
* @assert (array()) === false
*/
public function save($params, $show_query = false)
{
$extra_field = new ExtraField($this->type);
// Setting value to insert.
$value = $params['field_value'];
$value_to_insert = null;
if (is_array($value)) {
$value_to_insert = implode(';', $value);
} else {
$value_to_insert = Database::escape_string($value);
}
$params['field_value'] = $value_to_insert;
//If field id exists
$extra_field_info = $extra_field->get($params['field_id']);
if ($extra_field_info) {
switch ($extra_field_info['field_type']) {
case ExtraField::FIELD_TYPE_RADIO:
case ExtraField::FIELD_TYPE_SELECT:
case ExtraField::FIELD_TYPE_SELECT_MULTIPLE:
//$field_options = $session_field_option->get_field_options_by_field($params['field_id']);
//$params['field_value'] = split(';', $value_to_insert);
/*
if ($field_options) {
$check = false;
foreach ($field_options as $option) {
if (in_array($option['option_value'], $values)) {
$check = true;
break;
}
}
if (!$check) {
return false; //option value not found
}
} else {
return false; //enumerated type but no option found
}*/
break;
case ExtraField::FIELD_TYPE_TEXT:
case ExtraField::FIELD_TYPE_TEXTAREA:
break;
case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
if (is_array($value)) {
if (isset($value['extra_'.$extra_field_info['field_variable']]) &&
isset($value['extra_'.$extra_field_info['field_variable'].'_second'])
) {
$value_to_insert = $value['extra_'.$extra_field_info['field_variable']].'::'.$value['extra_'.$extra_field_info['field_variable'].'_second'];
} else {
$value_to_insert = null;
}
}
break;
default:
break;
}
if ($extra_field_info['field_type'] == ExtraField::FIELD_TYPE_TAG) {
$field_values = self::getAllValuesByItemAndFieldAndValue(
$params[$this->handler_id],
$params['field_id'],
$value
);
} else {
$field_values = self::get_values_by_handler_and_field_id(
$params[$this->handler_id],
$params['field_id']
);
}
$params['field_value'] = $value_to_insert;
$params['tms'] = api_get_utc_datetime();
$params[$this->author_id] = api_get_user_id();
// Insert
if (empty($field_values)) {
if ($extra_field_info['field_loggeable'] == 1) {
global $app;
switch($this->type) {
case 'question':
$extraFieldValue = new ChamiloLMS\Entity\QuestionFieldValues();
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setQuestionId($params[$this->handler_id]);
break;
case 'course':
$extraFieldValue = new ChamiloLMS\Entity\CourseFieldValues();
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setQuestionId($params[$this->handler_id]);
break;
case 'user':
$extraFieldValue = new ChamiloLMS\Entity\UserFieldValues();
$extraFieldValue->setUserId($params[$this->handler_id]);
$extraFieldValue->setAuthorId(api_get_user_id());
break;
case 'session':
$extraFieldValue = new ChamiloLMS\Entity\SessionFieldValues();
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setSessionId($params[$this->handler_id]);
break;
}
if (isset($extraFieldValue)) {
if (!empty($params['field_value'])) {
$extraFieldValue->setComment($params['comment']);
$extraFieldValue->setFieldValue($params['field_value']);
$extraFieldValue->setFieldId($params['field_id']);
$extraFieldValue->setTms(api_get_utc_datetime(null, false, true));
$app['orm.ems']['db_write']->persist($extraFieldValue);
$app['orm.ems']['db_write']->flush();
}
}
} else {
if ($extra_field_info['field_type'] == ExtraField::FIELD_TYPE_TAG) {
$option = new ExtraFieldOption($this->type);
$optionExists = $option->get($params['field_value']);
if (empty($optionExists)) {
$optionParams = array(
'field_id' => $params['field_id'],
'option_value' => $params['field_value']
);
$optionId = $option->saveOptions($optionParams);
} else {
$optionId = $optionExists['id'];
}
$params['field_value'] = $optionId;
if ($optionId) {
return parent::save($params, $show_query);
}
} else {
return parent::save($params, $show_query);
}
}
} else {
// Update
if ($extra_field_info['field_loggeable'] == 1) {
global $app;
switch($this->type) {
case 'question':
$extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\QuestionFieldValues')->find($field_values['id']);
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setQuestionId($params[$this->handler_id]);
break;
case 'course':
$extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\CourseFieldValues')->find($field_values['id']);
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setCourseCode($params[$this->handler_id]);
break;
case 'user':
$extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\UserFieldValues')->find($field_values['id']);
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setAuthorId(api_get_user_id());
break;
case 'session':
$extraFieldValue = $app['orm.ems']['db_write']->getRepository('ChamiloLMS\Entity\SessionFieldValues')->find($field_values['id']);
$extraFieldValue->setUserId(api_get_user_id());
$extraFieldValue->setSessionId($params[$this->handler_id]);
break;
}
if (isset($extraFieldValue)) {
if (!empty($params['field_value'])) {
/*
* If the field value is similar to the previous value then the comment will be the same
in order to no save in the log an empty record
*/
if ($extraFieldValue->getFieldValue() == $params['field_value']) {
if (empty($params['comment'])) {
$params['comment'] = $extraFieldValue->getComment();
}
}
$extraFieldValue->setComment($params['comment']);
$extraFieldValue->setFieldValue($params['field_value']);
$extraFieldValue->setFieldId($params['field_id']);
$extraFieldValue->setTms(api_get_utc_datetime(null, false, true));
$app['orm.ems']['db_write']->persist($extraFieldValue);
$app['orm.ems']['db_write']->flush();
}
}
} else {
$params['id'] = $field_values['id'];
return parent::update($params, $show_query);
}
}
}
}
/**
* Returns the value of the given extra field on the given resource
* @param int Item ID (It could be a session_id, course_id or user_id)
* @param int Field ID (the ID from the *_field table)
* @param bool Whether to transform the result to a human readable strings
* @return mixed A structured array with the field_id and field_value, or false on error
* @assert (-1,-1) === false
*/
public function get_values_by_handler_and_field_id($item_id, $field_id, $transform = false)
{
$field_id = intval($field_id);
$item_id = Database::escape_string($item_id);
$sql = "SELECT s.*, field_type FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf ON (s.field_id = sf.id)
WHERE {$this->handler_id} = '$item_id' AND
field_id = '".$field_id."'
ORDER BY id";
$result = Database::query($sql);
if (Database::num_rows($result)) {
$result = Database::fetch_array($result, 'ASSOC');
if ($transform) {
if (!empty($result['field_value'])) {
switch ($result['field_type']) {
case ExtraField::FIELD_TYPE_DOUBLE_SELECT:
$field_option = new ExtraFieldOption($this->type);
$options = explode('::', $result['field_value']);
// only available for PHP 5.4 :( $result['field_value'] = $field_option->get($options[0])['id'].' -> ';
$result = $field_option->get($options[0]);
$result_second = $field_option->get($options[1]);
if (!empty($result)) {
$result['field_value'] = $result['option_display_text'].' -> ';
$result['field_value'] .= $result_second['option_display_text'];
}
break;
case ExtraField::FIELD_TYPE_SELECT:
$field_option = new ExtraFieldOption($this->type);
$extra_field_option_result = $field_option->get_field_option_by_field_and_option(
$result['field_id'],
$result['field_value']
);
if (isset($extra_field_option_result[0])) {
$result['field_value'] = $extra_field_option_result[0]['option_display_text'];
}
break;
}
}
}
return $result;
} else {
return false;
}
}
/**
* @param string $tag
* @param int $field_id
* @param int $limit
* @return array
*/
public function searchValuesByField($tag, $field_id, $limit = 10)
{
$field_id = intval($field_id);
$limit = intval($limit);
$tag = Database::escape_string($tag);
$sql = "SELECT DISTINCT s.field_value, s.field_id
FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf ON (s.field_id = sf.id)
WHERE
field_id = '".$field_id."' AND
field_value LIKE '%$tag%'
ORDER BY field_value
LIMIT 0, $limit
";
$result = Database::query($sql);
$values = array();
if (Database::num_rows($result)) {
$values = Database::store_result($result, 'ASSOC');
}
return $values;
}
/**
* Gets a structured array of the original item and its extra values, using
* a specific original item and a field name (like "branch", or "birthdate")
* @param int Item ID from the original table
* @param string The name of the field we are looking for
* @return mixed Array of results, or false on error or not found
* @assert (-1,'') === false
*/
public function get_values_by_handler_and_field_variable($item_id, $field_variable, $transform = false)
{
$item_id = Database::escape_string($item_id);
$field_variable = Database::escape_string($field_variable);
$sql = "SELECT s.*, field_type FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf
ON (s.field_id = sf.id)
WHERE
{$this->handler_id} = '$item_id' AND
field_variable = '".$field_variable."'
ORDER BY id";
$result = Database::query($sql);
if (Database::num_rows($result)) {
$result = Database::fetch_array($result, 'ASSOC');
if ($transform) {
if ($result['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
if (!empty($result['field_value'])) {
$field_option = new ExtraFieldOption($this->type);
$options = explode('::', $result['field_value']);
// only available for PHP 5.4 :( $result['field_value'] = $field_option->get($options[0])['id'].' -> ';
$result = $field_option->get($options[0]);
$result_second = $field_option->get($options[1]);
if (!empty($result)) {
$result['field_value'] = $result['option_display_text'].' -> ';
$result['field_value'] .= $result_second['option_display_text'];
}
}
}
}
return $result;
} else {
return false;
}
}
/**
* Gets the ID from the item (course, session, etc) for which
* the given field is defined with the given value
* @param string Field (type of data) we want to check
* @param string Data we are looking for in the given field
* @return mixed Give the ID if found, or false on failure or not found
* @assert (-1,-1) === false
*/
public function get_item_id_from_field_variable_and_field_value($field_variable, $field_value, $transform = false)
{
$field_value = Database::escape_string($field_value);
$field_variable = Database::escape_string($field_variable);
$sql = "SELECT {$this->handler_id} FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf
ON (s.field_id = sf.id)
WHERE
field_value = '$field_value' AND
field_variable = '".$field_variable."'
";
$result = Database::query($sql);
if ($result !== false && Database::num_rows($result)) {
$result = Database::fetch_array($result, 'ASSOC');
return $result;
} else {
return false;
}
}
/**
* Get all values for a specific field id
* @param int Field ID
* @return mixed Array of values on success, false on failure or not found
* @assert (-1) === false
*/
public function get_values_by_field_id($field_id)
{
$field_id = intval($field_id);
$sql = "SELECT s.*, field_type FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf
ON (s.field_id = sf.id)
WHERE field_id = '".$field_id."' ORDER BY id";
$result = Database::query($sql);
if (Database::num_rows($result)) {
return Database::store_result($result, 'ASSOC');
}
return false;
}
/**
* @param int $itemId
* @param int $fieldId
* @return array
*/
public function getAllValuesByItemAndField($itemId, $fieldId)
{
$fieldId = intval($fieldId);
$itemId = intval($itemId);
$sql = "SELECT s.* FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf
ON (s.field_id = sf.id)
WHERE
field_id = '".$fieldId."' AND
{$this->handler_id} = '$itemId'
ORDER BY field_value";
$result = Database::query($sql);
if (Database::num_rows($result)) {
return Database::store_result($result, 'ASSOC');
}
return false;
}
/**
* @param int $itemId
* @param int $fieldId
* @param string $fieldValue
* @return array|bool
*/
public function getAllValuesByItemAndFieldAndValue($itemId, $fieldId, $fieldValue)
{
$fieldId = intval($fieldId);
$itemId = intval($itemId);
$fieldValue = Database::escape_string($fieldValue);
$sql = "SELECT s.* FROM {$this->table} s
INNER JOIN {$this->table_handler_field} sf
ON (s.field_id = sf.id)
WHERE
field_id = '".$fieldId."' AND
{$this->handler_id} = '$itemId' AND
field_value = $fieldValue
ORDER BY field_value";
$result = Database::query($sql);
if (Database::num_rows($result)) {
return Database::store_result($result, 'ASSOC');
}
return false;
}
/**
* Deletes all the values related to a specific field ID
* @param int Field ID
* @return void
* @assert ('a') == null
*/
public function delete_all_values_by_field_id($field_id)
{
$field_id = intval($field_id);
$sql = "DELETE FROM {$this->table} WHERE field_id = $field_id";
Database::query($sql);
}
/**
* Deletes values of a specific field for a specific item
* @param int Item ID (session id, course id, etc)
* @param int Field ID
* @return void
* @assert (-1,-1) == null
*/
public function delete_values_by_handler_and_field_id($item_id, $field_id)
{
$field_id = intval($field_id);
$item_id = Database::escape_string($item_id);
$sql = "DELETE FROM {$this->table} WHERE {$this->handler_id} = '$item_id' AND field_id = '".$field_id."' ";
Database::query($sql);
}
/**
* @param int $itemId
* @param int $fieldId
* @param int $fieldValue
*/
public function deleteValuesByHandlerAndFieldAndValue($itemId, $fieldId, $fieldValue)
{
$itemId = intval($itemId);
$fieldId = intval($fieldId);
$fieldValue = Database::escape_string($fieldValue);
$sql = "DELETE FROM {$this->table}
WHERE
{$this->handler_id} = '$itemId' AND
field_id = '".$fieldId."' AND
field_value = '$fieldValue'";
Database::query($sql);
}
/**
* Not yet implemented - Compares the field values of two items
* @param int Item 1
* @param int Item 2
* @return mixed Differential array generated from the comparison
*/
public function compare_item_values($item_id, $item_to_compare)
{
}
}

@ -29,6 +29,7 @@
$language_file = array('document');
require_once '../../../../../../inc/global.inc.php';
api_block_anonymous_users();
// Disabling access for anonymous users.
api_block_anonymous_users();

@ -249,12 +249,14 @@ function handle_uploaded_document(
$where_to_save = $base_work_dir.$upload_path;
// At least if the directory doesn't exist, tell so
if (!is_dir($where_to_save)) {
if ($output){
Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')');
}
return false;
}
if (!is_dir($where_to_save)) {
if (!mkdir($where_to_save, api_get_permissions_for_new_directories())) {
if ($output) {
Display::display_error_message(get_lang('DestDirectoryDoesntExist').' ('.$upload_path.')');
}
return false;
}
}
// Full path of the destination
$store_path = $where_to_save.$clean_name;
@ -441,14 +443,20 @@ function moveUploadedFile($file, $storePath)
*
* @see - enough_size() uses dir_total_space() function
*/
function enough_size($file_size, $dir, $max_dir_space) {
if ($max_dir_space) {
$already_filled_space = dir_total_space($dir);
if (($file_size + $already_filled_space) > $max_dir_space) {
return false;
}
}
return true;
function enough_size($file_size, $dir, $max_dir_space)
{
// If the directory is the archive directory, safely ignore the size limit
if (api_get_path(SYS_ARCHIVE_PATH) == $dir) {
return true;
}
if ($max_dir_space) {
$already_filled_space = dir_total_space($dir);
if (($file_size + $already_filled_space) > $max_dir_space) {
return false;
}
}
return true;
}

@ -53,14 +53,30 @@ class HTML_QuickForm_Select_Ajax extends HTML_QuickForm_select
$dataCondition = '$("#'.$this->getAttribute('name').'").select2("data", '.$result.')';
$tags = ', tags : function() { return '.$result.'} ';
}
$width = 'element';
$givenWidth = $this->getAttribute('width');
if (!empty($givenWidth)) {
$width = $givenWidth;
}
//Get the minimumInputLength for select2
$minimumInputLength = ($this->getAttribute('minimumInputLength') > 3)?
$this->getAttribute('minimumInputLength') :
3
;
$plHolder = $this->getAttribute('placeholder');
if (empty($plHolder)) {
$plHolder = get_lang('SelectAnOption');
}
$html .= '<script>
$(function() {
$("#'.$this->getAttribute('name').'").select2({
placeholder: "'.get_lang('SelectAnOption').'",
placeholder: "' . $plHolder . '",
allowClear: true,
width: "element",
minimumInputLength: 2,
width: "'.$width.'",
minimumInputLength: ' . $minimumInputLength . ',
// instead of writing the function to execute the request we use Select2s convenient helper
ajax: {
url: "'.$this->getAttribute('url').'",

@ -3229,16 +3229,18 @@ function api_get_item_visibility($_course, $tool, $id, $session=0)
return -1;
}
$tool = Database::escape_string($tool);
$id = Database::escape_string($id);
$id = intval($id);
$session = (int) $session;
$TABLE_ITEMPROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
$course_id = $_course['real_id'];
$course_id = intval($_course['real_id']);
$sql = "SELECT visibility FROM $TABLE_ITEMPROPERTY
WHERE c_id = $course_id AND
tool = '$tool' AND
ref = $id AND
(id_session = $session OR id_session = 0)
ORDER BY id_session DESC, lastedit_date DESC LIMIT 1";
ORDER BY id_session DESC, lastedit_date DESC
LIMIT 1";
$res = Database::query($sql);
if ($res === false || Database::num_rows($res) == 0) { return -1; }
$row = Database::fetch_array($res);

@ -341,14 +341,14 @@ class HTML_QuickForm extends HTML_Common
}
}
$course_id = api_get_course_int_id();
//If I'm in a course replace the default max filesize with the course limits
if (!empty($course_id)) {
$free_course_quota = DocumentManager::get_course_quota() - DocumentManager::documents_total_space();
if (empty($this->_maxFileSize) || $free_course_quota <= $this->_maxFileSize) {
$this->_maxFileSize = intval($free_course_quota);
}
}
// $course_id = api_get_course_int_id();
// //If I'm in a course replace the default max filesize with the course limits
// if (!empty($course_id)) {
// $free_course_quota = DocumentManager::get_course_quota() - DocumentManager::documents_total_space();
// if (empty($this->_maxFileSize) || $free_course_quota <= $this->_maxFileSize) {
// $this->_maxFileSize = intval($free_course_quota);
// }
// }
} // end constructor
// }}}

File diff suppressed because it is too large Load Diff

@ -556,11 +556,20 @@ class Tracking
/**
* Gets the score average from all tests in a course by student
*
* @param mixed Student(s) id
* @param string Course code
* @param int Exercise id (optional), filtered by exercise
* @param int Session id (optional), if param $session_id is null it'll return results including sessions, 0 = session is not filtered
* @return string value (number %) Which represents a round integer about the score average.
* @param $student_id
* @param $course_code
* @param int $exercise_id
* @param null $session_id
* @param int $active_filter 2 for consider all tests
* 1 for active <> -1
* 0 for active <> 0
* @param int $into_lp 1 for all exercises
* 0 for whitout LP
* @internal param \Student $mixed id
* @internal param \Course $string code
* @internal param \Exercise $int id (optional), filtered by exercise
* @internal param \Session $int id (optional), if param $session_id is null it'll return results including sessions, 0 = session is not filtered
* @return string value (number %) Which represents a round integer about the score average.
*/
public static function get_avg_student_exercise_score($student_id, $course_code, $exercise_id = 0, $session_id = null)
{
@ -583,8 +592,23 @@ class Tracking
$session_id = intval($session_id);
$condition_session = " AND session_id = $session_id ";
}
if ($active_filter == 1) {
$condition_active = 'AND active <> -1';
} elseif ($active_filter == 0) {
$condition_active = 'AND active <> 0';
} else {
$condition_active = '';
}
$condition_into_lp = '';
$select_lp_id = '';
if ($into_lp == 0) {
$condition_into_lp = 'AND orig_lp_id = 0 AND orig_lp_item_id = 0';
} else {
$select_lp_id = ', orig_lp_id as lp_id ';
}
$sql = "SELECT count(id) FROM $tbl_course_quiz
WHERE c_id = {$course_info['real_id']} AND active <> -1 $condition_quiz ";
WHERE c_id = {$course_info['real_id']} $condition_active $condition_quiz ";
$count_quiz = Database::fetch_row(Database::query($sql));
if (!empty($count_quiz[0]) && !empty($student_id)) {
@ -596,7 +620,7 @@ class Tracking
if (empty($exercise_id)) {
$sql = "SELECT id FROM $tbl_course_quiz
WHERE c_id = {$course_info['real_id']} AND active <> -1 $condition_quiz";
WHERE c_id = {$course_info['real_id']} $condition_active $condition_quiz";
$result = Database::query($sql);
$exercise_list = array();
$exercise_id = null;
@ -613,18 +637,19 @@ class Tracking
$count_quiz = Database::fetch_row(Database::query($sql));
$sql = "SELECT SUM(exe_result/exe_weighting*100) as avg_score, COUNT(*) as num_attempts
$select_lp_id
FROM $tbl_stats_exercise
WHERE exe_exo_id IN ('".$exercise_id."')
$condition_user AND
orig_lp_id = 0 AND
status = '' AND
exe_cours_id = '$course_code' AND
orig_lp_item_id = 0 $condition_session
exe_cours_id = '$course_code'
$condition_session
$condition_into_lp
ORDER BY exe_date DESC";
$res = Database::query($sql);
$row = Database::fetch_array($res);
$quiz_avg_score = 0;
$quiz_avg_score = null;
if (!empty($row['avg_score'])) {
$quiz_avg_score = round($row['avg_score'],2);
@ -636,7 +661,26 @@ class Tracking
if (is_array($student_id)) {
$quiz_avg_score = round($quiz_avg_score / count($student_id), 2);
}
return $quiz_avg_score;
if ($into_lp == 0) {
return $quiz_avg_score;
} else {
if (!empty($row['lp_id'])) {
$tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
$sql = "SELECT lp.name FROM $tbl_lp as lp, $tbl_course as c WHERE
c.code = '$course_code' AND
lp.id = ".$row['lp_id']." AND
lp.c_id = c.id
LIMIT 1;
";
$result = Database::query($sql);
$row_lp = Database::fetch_row($result);
$lp_name = $row_lp[0];
return array($quiz_avg_score, $lp_name);
} else {
return array($quiz_avg_score, null);
}
}
}
}
return null;
@ -644,41 +688,50 @@ class Tracking
/**
* Get count student's exercise COMPLETED attempts
* @param int tudent id
* @param string Course code
* @param int Exercise id
* @param int Learning path id (optional), for showing attempts inside a learning path $lp_id and $lp_item_id params are required.
* @param int Learning path item id (optional), for showing attempts inside a learning path $lp_id and $lp_item_id params are required.
*
* @return int count of attempts
* @param $student_id
* @param $course_code
* @param $exercise_id
* @param int $lp_id
* @param int $lp_item_id
* @param int $session_id
* @param int $find_all_lp 0 = just LP specified
* 1 = LP specified or whitout LP,
* 2 = all rows
* @internal param \Student $int id
* @internal param \Course $string code
* @internal param \Exercise $int id
* @internal param \Learning $int path id (optional), for showing attempts inside a learning path $lp_id and $lp_item_id params are required.
* @internal param \Learning $int path item id (optional), for showing attempts inside a learning path $lp_id and $lp_item_id params are required.
* @return int count of attempts
*/
public static function count_student_exercise_attempts(
$student_id,
$course_code,
$exercise_id,
$lp_id = 0,
$lp_item_id = 0,
$session_id = 0
) {
public static function count_student_exercise_attempts($student_id, $course_code, $exercise_id, $lp_id = 0, $lp_item_id = 0, $session_id = 0, $find_all_lp = 0) {
$course_code = Database::escape_string($course_code);
$student_id = intval($student_id);
$exercise_id = intval($exercise_id);
$session_id = intval($session_id);
$count_attempts = 0;
if (!empty($lp_id)) $lp_id = intval($lp_id);
if (!empty($lp_item_id)) $lp_id = intval($lp_item_id);
$tbl_stats_exercices = Database :: get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$sql = "SELECT COUNT(ex.exe_id) as essais FROM $tbl_stats_exercices AS ex
WHERE ex.exe_cours_id = '$course_code'
AND ex.exe_exo_id = $exercise_id
AND status = ''
AND orig_lp_id = $lp_id
AND orig_lp_item_id = $lp_item_id
AND exe_user_id= $student_id
AND session_id = $session_id ";
if ($find_all_lp == 1) {
$sql .= "AND (orig_lp_id = $lp_id OR orig_lp_id = 0)
AND (orig_lp_item_id = $lp_item_id OR orig_lp_item_id = 0)";
} elseif ($find_all_lp == 0) {
$sql .= "AND orig_lp_id = $lp_id
AND orig_lp_item_id = $lp_item_id";
}
$rs = Database::query($sql);
$row = Database::fetch_row($rs);
$count_attempts = $row[0];
@ -749,6 +802,162 @@ class Tracking
return $result.'%';
}
/**
* get teacher progress by course and session
* @param int course id
* @param int session id
* @return data array
*/
static function get_teachers_progress_by_course($courseId, $sessionId)
{
$course = api_get_course_info_by_id($courseId);
//get teachers
$sql = "SELECT scu.id_session, scu.id_user, s.name
FROM session_rel_course_rel_user scu, session s
WHERE scu.id_session = s.id
AND scu.status = 2
AND scu.visibility = 1
AND scu.course_code = '%s'
AND scu.id_session = %s";
$query = sprintf($sql,$course['code'], $sessionId);
$rs = Database::query($query);
$teachers = array();
while ($teacher = Database::fetch_array($rs,'ASSOC')) {
$teachers[] = $teacher;
}
foreach ($teachers as $teacher) {
//total documents added
$sql = "SELECT count(*) as total
FROM c_item_property
WHERE lastedit_type = 'DocumentAdded'
AND c_id = %s
AND insert_user_id = %s
AND id_session = %s";
$query = sprintf($sql,
$courseId,
$teacher['id_user'],
$teacher['id_session']
);
//error_log($query);
$rs = Database::query($query);
$totalDocuments = 0;
if ($rs) {
$row = Database::fetch_row($rs);
$totalDocuments = $row[0];
}
//total links added
$sql = "SELECT count(*) as total
FROM c_item_property
WHERE lastedit_type = 'LinkAdded'
AND c_id = %s
AND insert_user_id = %s
AND id_session = %s";
$query = sprintf($sql,
$courseId,
$teacher['id_user'],
$teacher['id_session']
);
$rs = Database::query($query);
$totalLinks = 0;
if ($rs) {
$row = Database::fetch_row($rs);
$totalLinks = $row[0];
}
//total forums added
$sql = "SELECT count(*) as total
FROM c_item_property
WHERE lastedit_type = 'ForumthreadVisible'
AND c_id = %s
AND insert_user_id = %s
AND id_session = %s";
$query = sprintf($sql,
$courseId,
$teacher['id_user'],
$teacher['id_session']
);
$rs = Database::query($query);
$totalForums = 0;
if ($rs) {
$row = Database::fetch_row($rs);
$totalForums = $row[0];
}
//total wikis added
$sql = "SELECT COUNT(DISTINCT(ref)) as total
FROM c_item_property
WHERE lastedit_type = 'WikiAdded'
AND c_id = %s
AND insert_user_id = %s
AND id_session = %s";
$query = sprintf($sql,
$courseId,
$teacher['id_user'],
$teacher['id_session']
);
$rs = Database::query($query);
$totalWikis = 0;
if ($rs) {
$row = Database::fetch_row($rs);
$totalWikis = $row[0];
}
//total works added
$sql = "SELECT COUNT(*) as total
FROM c_item_property
WHERE lastedit_type = 'DirectoryCreated'
AND tool = 'work'
AND c_id = %s
AND insert_user_id = %s
AND id_session = %s";
$query = sprintf($sql,
$courseId,
$teacher['id_user'],
$teacher['id_session']
);
$rs = Database::query($query);
$totalWorks = 0;
if ($rs) {
$row = Database::fetch_row($rs);
$totalWorks = $row[0];
}
//total announcements added
$sql = "SELECT COUNT(*) as total
FROM c_item_property
WHERE lastedit_type = 'AnnouncementAdded'
AND c_id = %s
AND insert_user_id = %s
AND id_session = %s";
$query = sprintf($sql,
$courseId,
$teacher['id_user'],
$teacher['id_session']
);
$rs = Database::query($query);
$totalAnnouncements = 0;
if ($rs) {
$row = Database::fetch_row($rs);
$totalAnnouncements = $row[0];
}
$tutor = get_user_info_by_id($teacher['id_user']);
$data[] = array(
'course' => $course['title'],
'session' => $teacher['name'],
'tutor' => $tutor['username'] . ' - ' . $tutor['lastname'] . ' ' . $tutor['firstname'],
'documents' => $totalDocuments,
'links' => $totalLinks,
'forums' => $totalForums,
'works' => $totalWorks,
'wikis' => $totalWikis,
'announcements' => $totalAnnouncements,
);
}
return $data;
}
/**
* Returns the average student progress in the learning paths of the given
* course.
@ -2368,46 +2577,132 @@ class Tracking
return $data;
}
/**
* Get total clicks by session
* @param int Session id (optional), if param $session_id is null(default) it'll return results including sessions, 0 = session is not filtered
* @return array data
* @todo implement total click by $course_id
* Get total clicks
* THIS FUNCTION IS NOT BEEN USED, IT WAS MEANT TO BE USE WITH track_e_course_access.date_from and track_e_course_access.date_to,
* BUT NO ROW MATCH THE CONDITION, IT SHOULD BE FINE TO USE IT WHEN YOU USE USER DEFINED DATES AND NO CHAMILO DATES
* @param int User Id
* @param int Course Id
* @param int Session Id (optional), if param $session_id is null(default) it'll return results including sessions, 0 = session is not filtered
* @param string Date from
* @param string Date to
* @return array Data
* @author César Perales cesar.perales@beeznest.com 2014-01-16
*/
public static function get_total_clicks_by_session($session_id = null)
public static function get_total_clicks($userId, $courseId, $sessionId = 0, $date_from = '', $date_to = '')
{
$course = api_get_course_info_by_id($courseId);
$tables = array(
TABLE_STATISTIC_TRACK_E_LASTACCESS => array('access_session_id','access_user_id'),
TABLE_STATISTIC_TRACK_E_ACCESS => array('access_session_id', 'access_user_id'),
#TABLE_STATISTIC_TRACK_E_LOGIN,
TABLE_STATISTIC_TRACK_E_DOWNLOADS => array('down_session_id', 'down_user_id'),
TABLE_STATISTIC_TRACK_E_LINKS => array('links_session_id', 'links_user_id'),
TABLE_STATISTIC_TRACK_E_ONLINE => array('session_id', 'login_user_id'),
TABLE_STATISTIC_TRACK_E_LASTACCESS => array(
'course' => 'access_cours_code',
'session' => 'access_session_id',
'user' => 'access_user_id',
'start_date'=> 'access_date',
),
TABLE_STATISTIC_TRACK_E_ACCESS => array(
'course' => 'access_cours_code',
'session' => 'access_session_id',
'user' => 'access_user_id',
'start_date'=> 'access_date',
),
#TABLE_STATISTIC_TRACK_E_LOGIN, array(,, 'login_date', 'logout_date');
TABLE_STATISTIC_TRACK_E_DOWNLOADS => array(
'course' => 'down_cours_id',
'session' => 'down_session_id',
'user' => 'down_user_id',
'start_date'=> 'down_date',
),
TABLE_STATISTIC_TRACK_E_LINKS => array(
'course' => 'links_cours_id',
'session' => 'links_session_id',
'user' => 'links_user_id',
'start_date'=> 'links_date',
),
TABLE_STATISTIC_TRACK_E_ONLINE => array(
'course' => 'course',
'session' => 'session_id',
'user' => 'login_user_id',
'start_date'=> 'login_date',
),
#TABLE_STATISTIC_TRACK_E_HOTPOTATOES,
TABLE_STATISTIC_TRACK_E_COURSE_ACCESS => array('session_id', 'user_id'),
TABLE_STATISTIC_TRACK_E_EXERCICES => array('session_id', 'exe_user_id'),
TABLE_STATISTIC_TRACK_E_ATTEMPT => array('session_id', 'user_id'),
/*TABLE_STATISTIC_TRACK_E_COURSE_ACCESS => array(
'course' => 'course_code',
'session' => 'session_id',
'user' => 'user_id',
'start_date'=> 'login_course_date',
'end_date' => 'logout_course_date',
),*/
TABLE_STATISTIC_TRACK_E_EXERCICES => array(
'course' => 'exe_cours_id',
'session' => 'session_id',
'user' => 'exe_user_id',
'start_date'=> 'exe_date',
),
TABLE_STATISTIC_TRACK_E_ATTEMPT => array(
'course' => 'course_code',
'session' => 'session_id',
'user' => 'user_id',
'start_date'=> 'tms',
),
#TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING,
#TABLE_STATISTIC_TRACK_E_DEFAULT,
TABLE_STATISTIC_TRACK_E_UPLOADS => array('upload_session_id', 'upload_user_id'),
TABLE_STATISTIC_TRACK_E_UPLOADS => array(
'course' => 'upload_cours_id',
'session' => 'upload_session_id',
'user' => 'upload_user_id',
'start_date'=> 'upload_date',
),
#TABLE_STATISTIC_TRACK_E_HOTSPOT,
#TABLE_STATISTIC_TRACK_E_ITEM_PROPERTY,
#TABLE_STATISTIC_TRACK_E_OPEN,
);
if (isset($_GET['session_id']) && !empty($_GET['session_id'])) {
$sessionId = intval($_GET['session_id']);
}
);
$error_sql = '';
foreach ($tables as $tableName => $fields) {
$sql = sprintf('SELECT %s as user, count(*) as total FROM %s WHERE %s = %s GROUP BY %s', $fields[1], $tableName, $fields[0], $sessionId, $fields[1]);
//If session is defined, add it to query
$where = '';
if (isset($sessionId) && !empty($sessionId)) {
$sessionField = $fields['session'];
$where .= " AND $sessionField = $sessionId";
}
//filter by date
if (!empty($date_from) && !empty($date_to)) {
$fieldStartDate = $fields['start_date'];
if (!isset($fields['end_date'])) {
$where .= sprintf(" AND ($fieldStartDate BETWEEN '%s' AND '%s' )", $date_from, $date_to) ;
} else {
$fieldEndDate = $fields['end_date'];
$where .= sprintf(" AND fieldStartDate >= '%s'
AND $fieldEndDate <= '%s'", $date_from, $date_to);
}
}
//query
$sql = "SELECT %s as user, count(*) as total
FROM %s
WHERE %s = '%s'
AND %s = %s
$where
GROUP BY %s";
$sql = sprintf($sql,
$fields['user'], //user field
$tableName, //FROM
$fields['course'], //course condition
$course['code'], //course condition
$fields['user'], //user condition
$userId, //user condition
$fields['user'] //GROUP BY
);
$rs = Database::query($sql);
//iterate query
if (Database::num_rows($rs) > 0) {
while ($row = Database::fetch_array($rs)) {
$data[$row['user']] = (isset($data[$row['user']])) ? $data[$row['user']] + $row[total]: $row['total'];
}
}
}
return $data;
}
@ -3496,27 +3791,249 @@ class Tracking
}
/**
* @param FormValidator $form
* @return mixed
*/
* @param FormValidator $form
* @return mixed
*/
public static function setUserSearchForm($form)
{
global $_configuration;
$form->addElement('text', 'keyword', get_lang('Keyword'));
$form->addElement('select', 'active', get_lang('Status'), array(1 => get_lang('Active'), 0 => get_lang('Inactive')));
if (isset($_configuration['save_user_last_login']) &&
$_configuration['save_user_last_login']
) {
$form->addElement(
'select',
'sleeping_days',
get_lang('InactiveDays'),
array('', 1 => 1, 5 => 5, 15 => 15, 30 => 30, 60 => 60, 90 => 90, 120 => 120)
);
global $_configuration;
$form->addElement('text', 'keyword', get_lang('Keyword'));
$form->addElement('select', 'active', get_lang('Status'), array(1 => get_lang('Active'), 0 => get_lang('Inactive')));
if (isset($_configuration['save_user_last_login']) &&
$_configuration['save_user_last_login']
) {
$form->addElement(
'select',
'sleeping_days',
get_lang('InactiveDays'),
array('', 1 => 1, 5 => 5, 15 => 15, 30 => 30, 60 => 60, 90 => 90, 120 => 120)
);
}
$form->addElement('button', 'submit', get_lang('Search'));
return $form;
}
/**
* Get the progress of a exercise
* @param int $sessionId The session ID (session.id)
* @param int $courseId The course ID (course.id)
* @param int $exerciseId The quiz ID (c_quiz.id)
* @param int $answer The answer status (0 = incorrect, 1 = correct, 2 = both)
* @param array $options An array of options you can pass to the query (limit, where and order)
* @return array An array with the data of exercise(s) progress
*/
public static function get_exercise_progress($sessionId = 0, $courseId = 0, $exerciseId = 0, $date_from, $date_to, $options = array())
{
$sessionId = intval($sessionId);
$courseId = intval($courseId);
$exerciseId = intval($exerciseId);
$date_from = Database::escape_string($date_from);
$date_to = Database::escape_string($date_to);
/*
* This method gets the data by blocks, as previous attempts at one single
* query made it take ages. The logic of query division is described below
*/
// Get tables names
$tuser = Database::get_main_table(TABLE_MAIN_USER);
$tquiz = Database::get_course_table(TABLE_QUIZ_TEST);
$tquiz_answer = Database::get_course_table(TABLE_QUIZ_ANSWER);
$tquiz_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
$tquiz_rel_question = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
$ttrack_exercises = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_EXERCICES);
$ttrack_attempt = Database::get_statistic_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
require_once api_get_path(SYS_CODE_PATH).'exercice/exercise.lib.php';
$sessions = array();
$courses = array();
// if session ID is defined but course ID is empty, get all the courses
// from that session
if (!empty($sessionId) && empty($courseId)) {
// $courses is an array of course int id as index and course details hash as value
$courses = SessionManager::get_course_list_by_session_id($sessionId);
$sessions[$sessionId] = api_get_session_info($sessionId);
} elseif (empty($sessionId) && !empty($courseId)) {
// if, to the contrary, course is defined but not sessions, get the sessions that include this course
// $sessions is an array like: [0] => ('id' => 3, 'name' => 'Session 35'), [1] => () etc;
$course = api_get_course_info_by_id($courseId);
$sessionsTemp = SessionManager::get_session_by_course($course['code']);
$courses[$courseId] = $course;
foreach ($sessionsTemp as $sessionItem) {
$sessions[$sessionItem['id']] = $sessionItem;
}
} elseif (!empty($courseId) && !empty($sessionId)) {
//none is empty
$course = api_get_course_info_by_id($courseId);
$courses[$courseId] = array($course['code']);
$courses[$courseId]['code'] = $course['code'];
$sessions[$sessionId] = api_get_session_info($sessionId);
} else {
//both are empty, not enough data, return an empty array
return array();
}
// Now we have two arrays of courses and sessions with enough data to proceed
// If no course could be found, we shouldn't return anything. Sessions can be empty (then we only return the pure-course-context results)
if (count($courses) < 1) {
return array();
}
$form->addElement('button', 'submit', get_lang('Search'));
return $form;
$data = array();
// The following loop is less expensive than what it seems:
// - if a course was defined, then we only loop through sessions
// - if a session was defined, then we only loop through courses
// - if a session and a course were defined, then we only loop once
foreach ($courses as $courseIdx => $courseData) {
$where = '';
$whereParams = array();
$whereCourseCode = $courseData['code'];
$whereSessionParams = '';
if (count($sessions > 0)) {
foreach ($sessions as $sessionIdx => $sessionData) {
if (!empty($sessionIdx)) {
$whereSessionParams .= $sessionIdx.',';
}
}
$whereSessionParams = substr($whereSessionParams,0,-1);
}
if (!empty($exerciseId)) {
$exerciseId = intval($exerciseId);
$where .= ' AND q.id = %d ';
$whereParams[] = $exerciseId;
}
/*
* This feature has been disabled for now, to avoid having to
* join two very large tables
//2 = show all questions (wrong and correct answered)
if ($answer != 2) {
$answer = intval($answer);
//$where .= ' AND qa.correct = %d';
//$whereParams[] = $answer;
}
*/
$limit = '';
if (!empty($options['limit'])) {
$limit = " LIMIT ".$options['limit'];
}
if (!empty($options['where'])) {
$where .= ' AND '.Database::escape_string($options['where']);
}
$order = '';
if (!empty($options['order'])) {
$order = " ORDER BY ".$options['order'];
}
if (!empty($date_to) && !empty($date_from)) {
$where .= sprintf(" AND (te.start_date BETWEEN '%s 00:00:00' AND '%s 23:59:59')", $date_from, $date_to);
}
$sql = "SELECT
te.session_id,
ta.id as attempt_id,
te.exe_user_id as user_id,
te.exe_id as exercise_attempt_id,
ta.question_id,
ta.answer as answer_id,
ta.tms as time,
te.exe_exo_id as quiz_id,
CONCAT ('c', q.c_id, '_e', q.id) as exercise_id,
q.title as quiz_title,
qq.description as description
FROM $ttrack_exercises te
INNER JOIN $ttrack_attempt ta ON ta.exe_id = te.exe_id
INNER JOIN $tquiz q ON q.id = te.exe_exo_id
INNER JOIN $tquiz_rel_question rq ON rq.exercice_id = q.id AND rq.c_id = q.c_id
INNER JOIN $tquiz_question qq ON qq.id = rq.question_id
AND qq.c_id = rq.c_id
AND qq.position = rq.question_order
AND ta.question_id = rq.question_id
WHERE te.exe_cours_id = '$whereCourseCode' ".(empty($whereSessionParams)?'':"AND te.session_id IN ($whereSessionParams)")."
AND q.c_id = $courseIdx
$where $order $limit";
$sql_query = vsprintf($sql, $whereParams);
// Now browse through the results and get the data
$rs = Database::query($sql_query);
$userIds = array();
$questionIds = array();
$answerIds = array();
while ($row = Database::fetch_array($rs)) {
//only show if exercise is visible
if (api_get_item_visibility($courseData, 'quiz', $row['exercise_id'])) {
$userIds[$row['user_id']] = $row['user_id'];
$questionIds[$row['question_id']] = $row['question_id'];
$answerIds[$row['question_id']][$row['answer_id']] = $row['answer_id'];
$row['session'] = $sessions[$row['session_id']];
$data[] = $row;
}
}
// Now fill questions data. Query all questions and answers for this test to avoid
$sqlQuestions = "SELECT tq.c_id, tq.id as question_id, tq.question, tqa.id_auto,
tqa.answer, tqa.correct, tq.position, tqa.id_auto as answer_id
FROM $tquiz_question tq, $tquiz_answer tqa
WHERE tqa.question_id =tq.id and tqa.c_id = tq.c_id
AND tq.c_id = $courseIdx AND tq.id IN (".implode(',',$questionIds).")";
$resQuestions = Database::query($sqlQuestions);
$answer = array();
$question = array();
while ($rowQuestion = Database::fetch_assoc($resQuestions)) {
$questionId = $rowQuestion['question_id'];
$answerId = $rowQuestion['answer_id'];
$answer[$questionId][$answerId] = array(
'position' => $rowQuestion['position'],
'question' => $rowQuestion['question'],
'answer' => $rowQuestion['answer'],
'correct' => $rowQuestion['correct']
);
$question[$questionId]['question'] = $rowQuestion['question'];
}
// Now fill users data
$sqlUsers = "SELECT user_id, username, lastname, firstname FROM $tuser WHERE user_id IN (".implode(',',$userIds).")";
$resUsers = Database::query($sqlUsers);
while ($rowUser = Database::fetch_assoc($resUsers)) {
$users[$rowUser['user_id']] = $rowUser;
}
foreach ($data as $id => $row) {
$rowQuestId = $row['question_id'];
$rowAnsId = $row['answer_id'];
$data[$id]['session'] = $sessions[$row['session_id']]['name'];
$data[$id]['firstname'] = $users[$row['user_id']]['firstname'];
$data[$id]['lastname'] = $users[$row['user_id']]['lastname'];
$data[$id]['username'] = $users[$row['user_id']]['username'];
$data[$id]['answer'] = $answer[$rowQuestId][$rowAnsId]['answer'];
$data[$id]['correct'] = ($answer[$rowQuestId][$rowAnsId]['correct'] == 0 ? get_lang('No') : get_lang('Yes'));
$data[$id]['question'] = $question[$rowQuestId]['question'];
$data[$id]['question_id'] = $rowQuestId;
$data[$id]['description'] = $row['description'];
}
/*
The minimum expected array structure at the end is:
attempt_id,
session name,
exercise_id,
quiz_title,
username,
lastname,
firstname,
time,
question_id,
question,
answer,
*/
}
return $data;
}
}

@ -932,11 +932,14 @@ class UserManager
}
/**
* @param array $ids
* @param null $active
* @return array
*/
public static function get_user_list_by_ids($ids = array(), $active = null)
* Get the users by ID
* @param array $ids student ids
* @param string $active
* @param string $order
* @param string $limit
* @return array $result student information
*/
public static function get_user_list_by_ids($ids = array(), $active = null, $order = null, $limit = null)
{
if (empty($ids)) {
return array();
@ -952,6 +955,14 @@ class UserManager
$sql .= ' AND active='.($active ? '1' : '0');
}
if (!is_null($order)) {
$sql .= ' ORDER BY ' . $order;
}
if (!is_null($limit)) {
$sql .= ' LIMIT ' . $limit;
}
$rs = Database::query($sql);
$result = array();
while ($row = Database::fetch_array($rs)) {

@ -763,6 +763,7 @@ if (isset($cidReset) && $cidReset) {
//Course login
if (isset($_user['user_id'])) {
event_course_login($_course['code'], $_user['user_id'], api_get_session_id());
error_log(__FILE__);
}
}
} else {
@ -822,7 +823,7 @@ if (isset($cidReset) && $cidReset) {
// these lines are usefull for tracking. Indeed we can have lost the id_session and not the cid.
// Moreover, if we want to track a course with another session it can be usefull
if (!empty($_GET['id_session'])) {
if (!empty($_GET['id_session']) && is_numeric($_GET['id_session'])) {
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
$sql = 'SELECT name FROM '.$tbl_session . ' WHERE id="'.intval($_SESSION['id_session']). '"';
$rs = Database::query($sql);
@ -885,19 +886,18 @@ if (isset($cidReset) && $cidReset) {
login_course_date > now() - INTERVAL $session_lifetime SECOND
ORDER BY login_course_date DESC LIMIT 0,1";
$result = Database::query($sql);
if (Database::num_rows($result) > 0) {
$i_course_access_id = Database::result($result,0,0);
//We update the course tracking table
$sql = "UPDATE $course_tracking_table SET logout_course_date = '$time', counter = counter+1
WHERE course_access_id = ".intval($i_course_access_id)." AND session_id = ".api_get_session_id();
//error_log($sql);
Database::query($sql);
//error_log(preg_replace('/\s+/',' ',$sql));
} else {
$sql="INSERT INTO $course_tracking_table (course_code, user_id, login_course_date, logout_course_date, counter, session_id)" .
"VALUES('".$course_code."', '".$_user['user_id']."', '$time', '$time', '1','".api_get_session_id()."')";
//error_log($sql);
Database::query($sql);
//error_log(preg_replace('/\s+/',' ',$sql));
}
}
}

@ -17,10 +17,10 @@ $ShowHotCoursesComment = "The hot courses list will be added in the index page";
$ShowHotCoursesTitle = "Show hot courses";
$EnableIframeInclusionComment = "Allowing arbitrary iframes in the HTML Editor will enhance the edition capabilities of the users, but it can represent a security risk. Please make sure you can rely on your users (i.e. you know who they are) before enabling this feature.";
$EnableIframeInclusionTitle = "Allow iframes in HTML Editor";
$MailTemplateRegistrationMessage = "Dear ((firstname)) ((lastname)),\n\nYou are registered on
((sitename)) with the following settings:\n\nUsername :
((username))\nPass : ((password))\n\nThe address of ((sitename)) is :
((url))\n\nIn case of trouble, contact us.\n\nYours sincerely
$MailTemplateRegistrationMessage = "Dear ((firstname)) ((lastname)),\n\nYou are registered on
((sitename)) with the following settings:\n\nUsername :
((username))\nPass : ((password))\n\nThe address of ((sitename)) is :
((url))\n\nIn case of trouble, contact us.\n\nYours sincerely
\n((admin_name)) ((admin_surname)).";
$MailTemplateRegistrationTitle = "New user on ((sitename))";
$AllowTeachersToCreateSessionsComment = "Teachers can create, edit and delete their own sessions.";
@ -48,6 +48,7 @@ $ConfigureHomePage = "Edit portal homepage";
$CourseCreateActiveToolsTitle = "Modules active upon course creation";
$CourseCreateActiveToolsComment = "Which tools have to be enabled (visible) by default when a new course is created?";
$SearchUsers = "Search users";
$SearchUser = "Search users";
$CreateUser = "Create user";
$ModifyInformation = "Edit information";
$ModifyUser = "Edit user";
@ -1365,7 +1366,7 @@ $EnabledImageMapsTitle = "Activate Image maps";
$EnabledImageMapsComment = "Activate the button to insert Image maps. This allows you to associate URLs to areas of an image, creating hotspots.";
$CourseTool = "Course tool";
$BigBlueButtonEnableTitle = "BigBlueButton videoconference tool";
$BigBlueButtonEnableComment = "Choose whether you want to enable the BigBlueButton videoconference tool. Once enabled, it will show as an additional course tool in all courses' homepage, and teachers will be able to launch a conference at any time. Learners will not be able to launch a conference, only join one. If you don't have a BigBlueButton server, please <a href=\"http://bigbluebutton.org/\" target=\"_blank\">set one up</a> or ask the <a href=\"http://www.chamilo.org/en/providers\" target=\"_blank\">Chamilo official providers</a> for a quote.
$BigBlueButtonEnableComment = "Choose whether you want to enable the BigBlueButton videoconference tool. Once enabled, it will show as an additional course tool in all courses' homepage, and teachers will be able to launch a conference at any time. Learners will not be able to launch a conference, only join one. If you don't have a BigBlueButton server, please <a href=\"http://bigbluebutton.org/\" target=\"_blank\">set one up</a> or ask the <a href=\"http://www.chamilo.org/en/providers\" target=\"_blank\">Chamilo official providers</a> for a quote.
BigBlueButton is a free (as in freedom *and* beer), but its installation requires a set of technical skills that might not be immediately available to all. You can install it on your own or seek professional help to assist you or do it for you. This help, however, will generate a certain cost. In the pure logic of the free software, we offer you the tools to make your work easier and recommend professionals (the Chamilo Official Providers) that will be able to help you if this were too difficult.";
$BigBlueButtonHostTitle = "BigBlueButton server host";
$BigBlueButtonHostComment = "This is the name of the server where your BigBlueButton server is running. Might be <i>localhost</i>, an IP address (e.g. 192.168.13.54) or a domain name (e.g. my.video.com).";
@ -1390,8 +1391,8 @@ $IncludeAsciiMathMlComment = "Activate this setting if you want to show ASCIIMat
$CourseHideToolsTitle = "Hide tools from teachers";
$CourseHideToolsComment = "Check the tools you want to hide from teachers. This will prohibit access to the tool.";
$MoveUserStats = "Move users results from/to a session";
$CompareUserResultsBetweenCoursesAndCoursesInASession = "This advanced tool allows you to manually improve the tracking of users results when moving from courses methodology to sessions methodology. In most cases, you won't need to use it.<br />
On this screen, you can compare results of users between the context of a standalone course, and the context of the same course inside a session.<br />
$CompareUserResultsBetweenCoursesAndCoursesInASession = "This advanced tool allows you to manually improve the tracking of users results when moving from courses methodology to sessions methodology. In most cases, you won't need to use it.<br />
On this screen, you can compare results of users between the context of a standalone course, and the context of the same course inside a session.<br />
Once you are sure about what to do, you can choose to move the tracking data of the students (exercises results and learning paths tracking) from a course to a session.";
$PDFExportWatermarkEnableTitle = "Enable watermark in PDF export";
$PDFExportWatermarkEnableComment = "By enabling this option, you can upload an image or a text that will be automatically added as watermark to all PDF exports of documents on the system.";
@ -1446,8 +1447,8 @@ $EnableAccessibilityFontResizeTitle = "Font resize accessibility feature";
$EnableAccessibilityFontResizeComment = "Enable this option to show a set of font resize options on the top-right side of your campus. This will allow visually impaired to read their course contents more easily.";
$GlobalEvent = "Platform event";
$SearchEnabledTitle = "Fulltext search";
$SearchEnabledComment = "This feature allows you to index most of the documents uploaded to your portal, then provide a search feature for users.<br />
This feature will not index documents that have already been uploaded, so it is important to enable (if wanted) at the beginning of your implementation.<br />
$SearchEnabledComment = "This feature allows you to index most of the documents uploaded to your portal, then provide a search feature for users.<br />
This feature will not index documents that have already been uploaded, so it is important to enable (if wanted) at the beginning of your implementation.<br />
Once enabled, a search box will appear in the courses list of every user. Searching for a specific term will bring a list of corresponding documents, exercises or forum topics, filtered depending on the availability of these contents to the user.";
$SpecificSearchFieldsAvailable = "Available custom search fields";
$XapianModuleInstalled = "Xapian module installed";

@ -9,18 +9,18 @@ $AreYouSureToEmptyAllTestResults = "Clear all learners results for every exercis
$CleanAllStudentsResultsForAllTests = "Are you sure to delete all test's results ?";
$TestFeedbackNotShown = "This test is configured not to display feedback to learners. Comments will not be seen at the end of the test, but may be useful for you, as teacher, when reviewing the question details.";
$FeedbackDisplayOptions = "How should we show the feedback/comment for each question? This option defines how it will be shown to the learner when taking the test. We recommend you try different options by editing your test options before having learners take it.";
$ImportAikenQuizExplanationExample = "This is the text for question 1
A. Answer 1
B. Answer 2
C. Answer 3
ANSWER: B
This is the text for question 2
A. Answer 1
B. Answer 2
C. Answer 3
D. Answer 4
ANSWER: D
$ImportAikenQuizExplanationExample = "This is the text for question 1
A. Answer 1
B. Answer 2
C. Answer 3
ANSWER: B
This is the text for question 2
A. Answer 1
B. Answer 2
C. Answer 3
D. Answer 4
ANSWER: D
ANSWER_EXPLANATION: this is an optional feedback comment that will appear next to the correct answer.";
$ImportAikenQuizExplanation = "The Aiken format comes in a simple text (.txt) file, with several question blocks, each separated by a blank line. The first line is the question, the answer lines are prefixed by a letter and a dot, and the correct answer comes next with the ANSWER: prefix. See example below.";
$ExerciseAikenErrorNoAnswerOptionGiven = "The imported file has at least one question without any answer (or the answers do not include the required prefix letter). Please make sure each question has at least one answer and that it is prefixed by a letter and a dot or a parenthesis, like this: A. answer one";
@ -36,18 +36,18 @@ $YesImSure = "Yes, I'm sure!";
$NoIWantToTurnBack = "No, I want to continue the exercise.";
$QuestionReused = "Question added in the exercise";
$QuestionCopied = "Question copied to the exercise";
$ZeroMeansNoQuestionWillBeSelectedMinusOneMeansThatAllQuestionsWillBeSelected = "-1 = All questions will be selected.
$ZeroMeansNoQuestionWillBeSelectedMinusOneMeansThatAllQuestionsWillBeSelected = "-1 = All questions will be selected.
0 = No questions will be selected.";
$EmailNotificationTemplateDescription = "You can customize the email sent to users when they finished the exercise. You can use tags like these:
1. {{ student.username }}
2. {{ student.firstname }}
3. {{ student.lastname }}
4. {{ student.official_code }}
5. {{ exercise.title }}
6. {{ exercise.start_time }}
7. {{ exercise.end_time }}
8. {{ course.title }}
$EmailNotificationTemplateDescription = "You can customize the email sent to users when they finished the exercise. You can use tags like these:
1. {{ student.username }}
2. {{ student.firstname }}
3. {{ student.lastname }}
4. {{ student.official_code }}
5. {{ exercise.title }}
6. {{ exercise.start_time }}
7. {{ exercise.end_time }}
8. {{ course.title }}
9. {{ course.code }}";
$EmailNotificationTemplate = "Email notification template";
$ExerciseEndButtonDisconnect = "Logout";
@ -585,4 +585,4 @@ $NoNegativeScore = "No negative score";
$GlobalMultipleAnswer = "Global multiple answer";
$AllQuestionsShort = "All";
$ProblemsRecordingUploadYourOwnAudioFile = "Problem recording? Upload your own audio file.";
?>
?>

@ -44,6 +44,7 @@ $ConfigureHomePage = "Configuración de la página principal";
$CourseCreateActiveToolsTitle = "Módulos activos al crear un curso";
$CourseCreateActiveToolsComment = "¿Qué herramientas serán activadas (visibles) por defecto al crear un curso?";
$SearchUsers = "Búsqueda de usuarios";
$SearchUser = "Buscar usuarios";
$CreateUser = "Crear usuario";
$ModifyInformation = "Modificar información";
$ModifyUser = "Modificar usuario";
@ -1361,9 +1362,9 @@ $EnabledImageMapsTitle = "Activar Mapas de imagen";
$EnabledImageMapsComment = "Activar el botón para insertar Mapas de imagen. Esto le permitirá asociar direcciones url a zonas de una imagen, generando zonas interactivas.";
$CourseTool = "Herramienta del curso";
$BigBlueButtonEnableTitle = "Herramienta de videoconferencia BigBlueButton";
$BigBlueButtonEnableComment = "Seleccione si desea habilitar la herramienta de videoconferencia BigBlueButton. Una vez activada, se mostrará como una herramienta en la página principal todos los curso. Los profesores podrán lanzar una videoconferencia en cualquier momento, pero los estudiantes sólo podrán unirse a una ya lanzada.
Si no dispone de un servidor BigBlueButton, pruebe a
<a href=\"http://bigbluebutton.org/\" target=\"_blank\">configurar uno</a> o pida ayuda a los <a href=\"http://www.chamilo.org/en/providers\" target=\"_blank\">proveedores oficiales de Chamilo</a>.
$BigBlueButtonEnableComment = "Seleccione si desea habilitar la herramienta de videoconferencia BigBlueButton. Una vez activada, se mostrará como una herramienta en la página principal todos los curso. Los profesores podrán lanzar una videoconferencia en cualquier momento, pero los estudiantes sólo podrán unirse a una ya lanzada.
Si no dispone de un servidor BigBlueButton, pruebe a
<a href=\"http://bigbluebutton.org/\" target=\"_blank\">configurar uno</a> o pida ayuda a los <a href=\"http://www.chamilo.org/en/providers\" target=\"_blank\">proveedores oficiales de Chamilo</a>.
BigBlueButton es libre, pero su instalación requiere ciertas habilidades técnicas que no todo el mundo posee. Puede instalarlo por su cuenta o buscar ayuda profesional con el consiguiente costo. En la lógica del software libre, nosotros le ofrecemos las herramientas para hacer más fácil su trabajo y le recomendamos profesionales (los proveedores oficiales de Chamilo) que serán capaces de ayudarle.";
$BigBlueButtonHostTitle = "Servidor BigBlueButton";
$BigBlueButtonHostComment = "Este es el nombre del servidor donde su servidor BigBlueButton está ejecutándose. Puede ser localhost, una dirección IP (ej., 192.168.14.54) o un nombre de dominio (por ej., my.video.com).";
@ -1374,7 +1375,7 @@ $AsciiSvgComment = "Activación del editor de gráficos matemáticos (ASCIIsvg)"
$Text2AudioTitle = "Activar servicios de conversión de texto en audio";
$Text2AudioComment = "Herramienta on-line para convertir texto en voz. Utiliza tecnología y sistemas de síntesis del habla para ofrecer recursos de voz.";
$ShowUsersFoldersTitle = "Mostrar las carpetas de los usuarios en la herramienta documentos";
$ShowUsersFoldersComment = "
$ShowUsersFoldersComment = "
Esta opción le permitirá mostrar u ocultar a los profesores las carpetas que el sistema genera para cada usuario que visita la herramienta documentos o envía un archivo a través del editor web. Si muestra estas carpetas a los profesores, éstos podrán hacerlas visibles o no a los estudiantes y permitirán a cada estudiante tener un lugar específico en el curso donde, no sólo almacenar documentos, sino donde también podrán crear y modificar páginas web y poder exportarlas a pdf, realizar dibujos, realizar plantillas web personales, enviar archivos, así como crear, mover y eliminar subdirectorios y archivos, y sacar copias de seguridad de sus carpetas. Cada usuario del curso dispondrá de un completo gestor de documentos. Además, recuerde que cualquier usuario podrá copiar un archivo, que sea visible, de cualquier carpeta de la herramienta documentos (sea o no la suya) a su portafolios o área personal de documentos de la red social, donde estará disponible para que lo pueda usar en otros cursos.";
$ShowDefaultFoldersTitle = "Mostrar en la herramienta documentos las carpetas que contienen los recursos multimedia suministrados por defecto.";
$ShowDefaultFoldersComment = "Las carpetas de archivos multimedia suministradas por defecto contienen archivos de libre distribución organizados en las categorías de video, audio, imagen y animaciones flash que para utilizar en sus cursos. Aunque las oculte en la herramienta documentos, podrá seguir usándolas en el editor web de la plataforma.";
@ -1389,8 +1390,8 @@ $IncludeAsciiMathMlComment = "Active este parámetro si desea mostrar fórmulas
$CourseHideToolsTitle = "Ocultar las herramientas a los docentes";
$CourseHideToolsComment = "Seleccione las herramientas que desea esconder del docente. Esto prohibirá el acceso a la herramienta.";
$MoveUserStats = "Mover los resultados de los usuarios desde/hacia una sesión de formación";
$CompareUserResultsBetweenCoursesAndCoursesInASession = "Esta herramienta avanzada le permite mejorar manualmente el seguimiento de los resultados de los usuarios cuando cambia de un modelo de cursos a un modelo de sesiones de formación. En una mayoría de casos, no necesitará usarla.<br />
En esta pantalla, puede comparar los resultados que los usuarios tienen en el contexto de un curso y en el contexto del mismo curso dentro de una sesión de formación.<br />
$CompareUserResultsBetweenCoursesAndCoursesInASession = "Esta herramienta avanzada le permite mejorar manualmente el seguimiento de los resultados de los usuarios cuando cambia de un modelo de cursos a un modelo de sesiones de formación. En una mayoría de casos, no necesitará usarla.<br />
En esta pantalla, puede comparar los resultados que los usuarios tienen en el contexto de un curso y en el contexto del mismo curso dentro de una sesión de formación.<br />
Una vez que decidida cuál es el mejor contexto para el seguimiento (resultados de ejercicios y seguimiento de lecciones), podrá moverlo de un curso a una sesión.";
$PDFExportWatermarkEnableTitle = "Marcas de agua en las exportaciones a PDF";
$PDFExportWatermarkEnableComment = "Si activa esta opción podrá cargar una imagen o un texto que serán automáticamente añadidos como marca de agua en los documentos resultantes de todas las exportaciones a PDF que realice el sistema.";
@ -1445,8 +1446,8 @@ $EnableAccessibilityFontResizeTitle = "Funcionalidad de redimensionamiento de fu
$EnableAccessibilityFontResizeComment = "Activar esta opción mostrará una serie de opciones de redimensionamiento de fuentes en la parte superior derecha de su campus. Esto permitirá a las personas con problemas de vista leer más fácilmente los contenidos de sus cursos.";
$GlobalEvent = "Evento de la plataforma";
$SearchEnabledTitle = "Búsqueda a texto completo";
$SearchEnabledComment = "Esta funcionalidad permite la indexación de la mayoría de los documentos subidos a su portal, con lo que permite la búsqueda para los usuarios.<br />
Esta funcionalidad no indexa los documentos que ya fueron subidos, por lo que es importante (si se quiere) activarla al comienzo de su implementación.<br />
$SearchEnabledComment = "Esta funcionalidad permite la indexación de la mayoría de los documentos subidos a su portal, con lo que permite la búsqueda para los usuarios.<br />
Esta funcionalidad no indexa los documentos que ya fueron subidos, por lo que es importante (si se quiere) activarla al comienzo de su implementación.<br />
Una vez activada, una caja de búsqueda aparecerá en la lista de cursos de cada usuario. Buscar un término específico suministra una lista de documentos, ejercicios o temas de foro correspondientes, filtrados dependiendo de su disponibilidad para el usuario.";
$SpecificSearchFieldsAvailable = "Campos de búsqueda personalizados disponibles";
$XapianModuleInstalled = "Módulo Xapian instalado";
@ -1604,37 +1605,37 @@ $GradebookEnableLockingTitle = "Activar bloqueo de Evaluaciones por los profesor
$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.";
$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/inc/conf/auth.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.</div>";
$ShibbolethMainActivateTitle = "<h3>Autenticación Shibboleth</h3>";
$ShibbolethMainActivateComment = "En primer lugar, tiene que configurar Shibboleth para su servidor web.
Para configurarlo en Chamilo:
editar el archivo <strong> main/auth/shibboleth/config/aai.class.php</strong>
Modificar valores de \$result con el nombre de los atributos de Shibboleth
\$result->unique_id = 'mail';
\$result->firstname = 'cn';
\$result->lastname = 'uid';
\$result->email = 'mail';
\$result->language = '-';
\$result->gender = '-';
\$result->address = '-';
\$result->staff_category = '-';
\$result->home_organization_type = '-';
\$result->home_organization = '-';
\$result->affiliation = '-';
\$result->persistent_id = '-';
...
$ShibbolethMainActivateComment = "En primer lugar, tiene que configurar Shibboleth para su servidor web.
Para configurarlo en Chamilo:
editar el archivo <strong> main/auth/shibboleth/config/aai.class.php</strong>
Modificar valores de \$result con el nombre de los atributos de Shibboleth
\$result->unique_id = 'mail';
\$result->firstname = 'cn';
\$result->lastname = 'uid';
\$result->email = 'mail';
\$result->language = '-';
\$result->gender = '-';
\$result->address = '-';
\$result->staff_category = '-';
\$result->home_organization_type = '-';
\$result->home_organization = '-';
\$result->affiliation = '-';
\$result->persistent_id = '-';
...
Ir a Plug-in para añadir el botón 'Shibboleth Login' en su campus de Chamilo.";
$LdapDescriptionTitle = "<h3>Autentificacion LDAP</h3>";
$FacebookMainActivateTitle = "Autenticación con Facebook";
$FacebookMainActivateComment = "En primer lugar, se tiene que crear una aplicación de Facebook (ver https://developers.facebook.com/apps) con una cuenta de Facebook. En los parámetros de aplicaciones de Facebook, el valor de dirección URL del sitio debe tener \"una acción = fbconnect\" un parámetro GET (http://mychamilo.com/?action=fbconnect, por ejemplo).
Entonces, editar el archivo <strong> main/auth/external_login/facebook.conf.php </strong>
e ingresar en \"appId\" y \"secret\" los valores de \$facebook_config.
$FacebookMainActivateComment = "En primer lugar, se tiene que crear una aplicación de Facebook (ver https://developers.facebook.com/apps) con una cuenta de Facebook. En los parámetros de aplicaciones de Facebook, el valor de dirección URL del sitio debe tener \"una acción = fbconnect\" un parámetro GET (http://mychamilo.com/?action=fbconnect, por ejemplo).
Entonces, editar el archivo <strong> main/auth/external_login/facebook.conf.php </strong>
e ingresar en \"appId\" y \"secret\" los valores de \$facebook_config.
Ir a Plug-in para añadir un botón configurable \"Facebook Login\" para el campus de Chamilo.";
$LanguagePriority1Title = "Prioridad del idioma 1";
$LanguagePriority2Title = "Prioridad del idioma 2";

@ -297,7 +297,7 @@ $DashboardBlocks = "Bloques del panel de control";
$DashboardList = "Lista del panel de control";
$YouHaveNotEnabledBlocks = "No ha habilitado ningún bloque";
$BlocksHaveBeenUpdatedSuccessfully = "Los bloques han sido actualizados";
$AttendanceSheetDescription = "Las listas de asistencia permiten registrar las faltas de asistencia de los estudiantes. En caso de ausencia de un estudiante, el profesor deberá registrarlo manualmente en la casilla correspondiente.
$AttendanceSheetDescription = "Las listas de asistencia permiten registrar las faltas de asistencia de los estudiantes. En caso de ausencia de un estudiante, el profesor deberá registrarlo manualmente en la casilla correspondiente.
Es posible crear más de una lista de asistencia por cada curso; así por ejemplo, podrá registrar separadamente la asistencia a las clases teóricas y prácticas.";
$AttendanceSheetReport = "Informe de hojas de asistencia";
$YouDoNotHaveDoneAttendances = "No tiene asistencias";
@ -379,4 +379,10 @@ $FollowedSessions = "Sesiones seguidas";
$FollowedCourses = "Cursos seguidos";
$FollowedUsers = "Usuarios seguidos";
$Timeline = "Línea del tiempo";
$QuestionId = "ID de pregunta";
$ExerciseId = "ID de ejercicio";
$QuestionTitle = "Título pregunta";
$DisplayGradeOverview = "Reporte de Notas por Curso";
$LpGradeReport = "Reporte de Notas por Curso";
$FinalScore = "Nota Final";
?>

@ -398,4 +398,5 @@ $AssessmentQuestions = "¿ Cómo van a ser evaluados los estudiantes ? ¿ Cuále
$AssessmentInformation = "Ejemplos de las preguntas de examen. Criterios de evaluación. Pistas y trucos.";
$UploadADocument = "Subir un documento";
$LowerCaseUser = "usuario";
$ChooseEvaluation = "Seleccione la Evaluación";
?>

@ -89,7 +89,7 @@ $table_title = ($session_name? Display::return_icon('session.png', get_lang('Ses
Display::return_icon('user.png', get_lang('User'), array(), ICON_SIZE_SMALL).' '.$name;
echo Display::page_header($table_title);
echo Display::page_subheader('<h3>'.Display::return_icon('learnpath.png', get_lang('ToolLearnpath'), array(), ICON_SIZE_SMALL).' '.$lp_title.'</h3>');
//Needed in newscorm/lp_stats.php
$list = learnpath :: get_flat_ordered_items_list($lp_id, 0, $course_info['real_id']);
@ -101,8 +101,8 @@ if ($export_csv) {
ob_start();
require_once api_get_path(SYS_CODE_PATH).'newscorm/lp_stats.php';
$tracking_content = ob_get_contents();
ob_end_clean();
ob_end_clean();
echo api_utf8_decode($tracking_content, $charset);
}
Display :: display_footer();

@ -202,8 +202,7 @@ if ($check) {
}
Security::clear_token();
}
//Generate a new token
// user info
$user_info = api_get_user_info($student_id);
@ -861,7 +860,8 @@ if (empty($_GET['details'])) {
<table class="data_table">
<tr>
<th><?php echo get_lang('Exercices'); ?></th>
<th><?php echo get_lang('AverageScore').' '.Display :: return_icon('info3.gif', get_lang('AverageScore'), array('align' => 'absmiddle', 'hspace' => '3px')) ?></th>
<th><?php echo get_lang('LearningPath');?></th>
<th><?php echo get_lang('AvgCourseScore').' '.Display :: return_icon('info3.gif', get_lang('AverageScore'), array('align' => 'absmiddle', 'hspace' => '3px')) ?></th>
<th><?php echo get_lang('Attempts'); ?></th>
<th><?php echo get_lang('LatestAttempt'); ?></th>
<th><?php echo get_lang('AllAttempts'); ?></th>
@ -878,7 +878,6 @@ if (empty($_GET['details'])) {
$t_quiz = Database :: get_course_table(TABLE_QUIZ_TEST);
$sql_exercices = "SELECT quiz.title, id FROM " . $t_quiz . " AS quiz
WHERE quiz.c_id = ".$info_course['real_id']." AND
active='1' AND
(quiz.session_id = $session_id OR quiz.session_id = 0)
ORDER BY quiz.title ASC ";
@ -887,14 +886,23 @@ if (empty($_GET['details'])) {
if (Database :: num_rows($result_exercices) > 0) {
while ($exercices = Database :: fetch_array($result_exercices)) {
$exercise_id = intval($exercices['id']);
$count_attempts = Tracking::count_student_exercise_attempts($student_id, $course_code, $exercise_id, 0, 0, $session_id);
$score_percentage = Tracking::get_avg_student_exercise_score($student_id, $course_code, $exercise_id, $session_id);
$lp_name = '';
$count_attempts = Tracking::count_student_exercise_attempts($student_id, $course_code, $exercise_id, 0, 0, $session_id, 2);
$score_percentage = Tracking::get_avg_student_exercise_score($student_id, $course_code, $exercise_id, $session_id, 1, 0);
if (!isset($score_percentage) && $count_attempts > 0) {
$scores_lp = Tracking::get_avg_student_exercise_score($student_id, $course_code, $exercise_id, $session_id, 2, 1);
$score_percentage = $scores_lp[0];
$lp_name = $scores_lp[1];
} else {
$lp_name = '-';
}
$lp_name = (!empty($lp_name))? $lp_name: get_lang('NoLearnpath');
$csv_content[] = array (
$exercices['title'],
$score_percentage . '%',
$count_attempts
);
if ($i % 2) $css_class = 'row_odd';
@ -902,7 +910,17 @@ if (empty($_GET['details'])) {
echo '<tr class="'.$css_class.'"><td>'.$exercices['title'].'</td>';
echo '<td>';
echo '<td>';
if (!empty($lp_name)) {
echo $lp_name;
} else {
echo '-';
}
echo '</td>';
echo '<td>';
if ($count_attempts > 0) {
echo $score_percentage . '%';
@ -920,9 +938,7 @@ if (empty($_GET['details'])) {
exe_user_id ="'.$student_id.'" AND
exe_cours_id ="'.$course_code.'" AND
session_id ="'.$session_id.'" AND
status = "" AND
orig_lp_id = 0 AND
orig_lp_item_id = 0
status = ""
ORDER BY exe_date DESC LIMIT 1';
$result_last_attempt = Database::query($sql_last_attempt);
if (Database :: num_rows($result_last_attempt) > 0) {

@ -274,7 +274,7 @@ class MySpace {
* Display a sortable table that contains an overview off all the progress of the user in a session
* @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
*/
public function display_tracking_lp_progress_overview($sessionId = '', $courseId = '') {
public static function display_tracking_lp_progress_overview($sessionId = '', $courseId = '', $date_from, $date_to) {
$course = api_get_course_info_by_id($courseId);
/**
@ -316,7 +316,7 @@ class MySpace {
$action_links = '';
// jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_lp_progress&session_id=' . intval($sessionId) . '&course_id=' . intval($courseId);
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_lp_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
//Table Id
$tableId = 'lpProgress';
@ -344,13 +344,17 @@ class MySpace {
}
/**
* Display a sortable table that contains an overview off all the progress of the user in a session
* @param int $sessionId The session ID
* @param int $courseId The course ID
* @param int $exerciseId The quiz ID
* @param int $answer Answer status (0 = incorrect, 1 = correct, 2 = both)
* @return string HTML array of results formatted for gridJS
* @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
*/
function display_tracking_exercise_progress_overview($sessionId = 0, $courseId = 0, $exerciseId = 0, $answer = 2) {
static function display_tracking_exercise_progress_overview($sessionId = 0, $courseId = 0, $exerciseId = 0, $date_from, $date_to) {
/**
* Column name
* The order is important you need to check the $column variable in the model.ajax.php file
* Column names
* The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file
*/
$columns = array(
get_lang('Session'),
@ -362,6 +366,7 @@ class MySpace {
get_lang('Time'),
get_lang('QuestionId'),
get_lang('QuestionTitle'),
get_lang('WorkDescription'),
get_lang('Answer'),
get_lang('Correct'),
);
@ -370,23 +375,23 @@ class MySpace {
* Column config
*/
$column_model = array(
array('name'=>'session', 'index'=>'session', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'exercise_id', 'index'=>'exercise_id', 'align'=>'left', 'search' => 'true'),
array('name'=>'quiz_title', 'index'=>'quiz_title', 'align'=>'left', 'search' => 'true'),
array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true'),
array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'),
array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'),
array('name'=>'time', 'index'=>'time', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'question_id', 'index'=>'question_id', 'align'=>'left', 'search' => 'true'),
array('name'=>'question', 'index'=>'question', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'answer', 'index'=>'answer', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'correct', 'index'=>'correct', 'align'=>'left', 'search' => 'true'),
array('name'=>'session', 'index'=>'session', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'exercise_id', 'index'=>'exercise_id', 'align'=>'left', 'search' => 'true'),
array('name'=>'quiz_title', 'index'=>'quiz_title', 'align'=>'left', 'search' => 'true'),
array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true'),
array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'),
array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'),
array('name'=>'time', 'index'=>'time', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'question_id', 'index'=>'question_id', 'align'=>'left', 'search' => 'true'),
array('name'=>'question', 'index'=>'question', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'description', 'index'=>'description', 'align'=>'left', 'width' => '550', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'answer', 'index'=>'answer', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
array('name'=>'correct', 'index'=>'correct', 'align'=>'left', 'search' => 'true', 'wrap_cell' => "true"),
);
//get dinamic column names
//get dynamic column names
$action_links = '';
// jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_progress&session_id=' . intval($sessionId) . '&course_id=' . intval($courseId) . '&exercise_id=' . intval($exerciseId) . '&answer=' . intval($answer);
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_exercise_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&exercise_id=' . $exerciseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
//Autowidth
$extra_params['autowidth'] = 'true';
@ -395,7 +400,7 @@ class MySpace {
$extra_params['height'] = 'auto';
$tableId = 'exerciseProgressOverview';
$table = Display::grid_js($tableId, $url, $columns, $column_model, $extra_params, array(), $action_links, true);
$table = Display::grid_js($tableId, $url, $columns, $column_model, $extra_params, array(), '', true);
$return = '<script>$(function() {'. $table .
'jQuery("#'.$tableId.'").jqGrid("navGrid","#'.$tableId.'_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
@ -410,11 +415,126 @@ class MySpace {
$return .= Display::grid_html($tableId);
return $return;
}
/**
* Display a sortable table that contains an overview off all the progress of the user in a session
* @param int $sessionId The session ID
* @param int $courseId The course ID
* @param null $date_from
* @param null $date_to
* @internal param int $exerciseId The quiz ID
* @internal param int $answer Answer status (0 = incorrect, 1 = correct, 2 = both)
* @return string HTML array of results formatted for gridJS
* @author Francis Gonzales <francis.gonzales@beeznest.com>, Beeznest Team
*/
static function display_tracking_grade_overview($sessionId = 0, $courseId = 0, $date_from = null, $date_to = null)
{
/**
* Column names
* The column order is important. Check $column variable in the main/inc/ajax/model.ajax.php file
*/
$objExercise = new Exercise();
$exercises = $objExercise->getExercisesByCouseSession($courseId, $sessionId);
$cntExer = 4;
if (!empty($exercises)) {
$cntExer += count($exercises);
}
$column = array();
$column_model = array();
$i = 1;
//Get dynamic column names
foreach (range(1, $cntExer) as $cnt) {
switch ($cnt) {
case 1:
$column[] = get_lang('Section');
$column_model[] = array(
'name' => 'session',
'index' => 'session',
'align' => 'center',
'search' => 'true',
);
break;
case 2:
$column[] = get_lang('Username');
$column_model[] = array(
'name' => 'username',
'index' => 'username',
'align' => 'center',
'search' => 'true',
);
break;
case 3:
$column[] = get_lang('FirstName');
$column_model[] = array(
'name' => 'name',
'index' => 'name',
'align' => 'left',
'search' => 'true',
);
break;
case $cntExer:
$column[] = get_lang('FinalScore');
$column_model[] = array(
'name' => 'finalscore',
'index' => 'finalscore',
'align' => 'center',
'search' => 'true',
'wrap_cell' => "true"
);
break;
default:
$title = "";
if (!empty($exercises[$cnt - 4]['title'])) {
$title = ucwords(strtolower(trim($exercises[$cnt - 4]['title'])));
}
$column[] = $title;
$column_model[] = array(
'name' => 'exer' . $i,
'index' => 'exer' . $i,
'align' => 'center',
'search' => 'true',
'wrap_cell' => "true"
);
$i++;
break;
}
}
//end get dynamic column names
// jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH) . 'model.ajax.php?a=get_exercise_grade&session_id=' . $sessionId . '&course_id=' . $courseId;
//Autowidth
$extra_params['autowidth'] = 'true';
//height auto
$extra_params['height'] = 'auto';
$tableId = 'exerciseGradeOverview';
$table = Display::grid_js($tableId, $url, $column, $column_model, $extra_params, array(), '', true);
$return = '<script>$(function() {' . $table .
'jQuery("#' . $tableId . '").jqGrid("navGrid","#' . $tableId . '_pager",{view:false, edit:false, add:false, del:false, search:false, excel:true});
jQuery("#' . $tableId . '").jqGrid("navButtonAdd","#' . $tableId . '_pager",{
caption:"",
title:"' . get_lang('ExportExcel') . '",
onClickButton : function () {
jQuery("#' . $tableId . '").jqGrid("excelExport",{"url":"' . $url . '&export_format=xls"});
}
});
});</script>';
$return .= Display::grid_html($tableId);
return $return;
}
/**
* Display a sortable table that contains an overview off all the progress of the user in a session
* @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
*/
function display_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $answer = 2) {
function display_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to) {
$course = api_get_course_info_by_id($courseId);
/**
@ -451,7 +571,7 @@ class MySpace {
$action_links = '';
// jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_survey_overview&session_id=' . intval($sessionId) . '&course_id=' . intval($courseId) . '&survey_id=' . intval($surveyId);
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_survey_overview&session_id=' . $sessionId . '&course_id=' . $courseId . '&survey_id=' . $surveyId . '&date_to=' . $date_to . '&date_from=' . $date_from;
//Table Id
$tableId = 'lpProgress';
@ -481,7 +601,7 @@ class MySpace {
* Display a sortable table that contains an overview off all the progress of the user in a session
* @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
*/
function display_tracking_progress_overview($sessionId = 0, $courseId = 0) {
static function display_tracking_progress_overview($sessionId = 0, $courseId = 0, $date_from, $date_to) {
//The order is important you need to check the the $column variable in the model.ajax.php file
$columns = array(
@ -490,15 +610,13 @@ class MySpace {
get_lang('Username'),
#get_lang('Profile'),
get_lang('Total'),
get_lang('CourseDescription'),
get_lang('Courses'),
get_lang('LearningPaths'),
get_lang('Exercises'),
get_lang('Forums'),
get_lang('Assignments'),
get_lang('ToolWiki'),
get_lang('ToolSurvey'),
//course description
get_lang('CourseDescriptionProgress'),
//Learning paths
get_lang('LearnpathsTotal'),
get_lang('LearnpathsDone'),
@ -534,56 +652,54 @@ class MySpace {
//Column config
$column_model = array(
array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left', 'search' => 'true'),
array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left', 'search' => 'true'),
array('name'=>'username', 'index'=>'username', 'align'=>'left', 'search' => 'true'),
#array('name'=>'profile', 'index'=>'username', 'align'=>'left', 'search' => 'true'),
array('name'=>'total', 'index'=>'total', 'align'=>'left', 'search' => 'true'),
array('name'=>'courses', 'index'=>'courses', 'align'=>'left', 'search' => 'true'),
array('name'=>'lessons', 'index'=>'lessons', 'align'=>'left', 'search' => 'true'),
array('name'=>'exercises', 'index'=>'exercises', 'align'=>'left', 'search' => 'true'),
array('name'=>'forums', 'index'=>'forums', 'align'=>'left', 'search' => 'true'),
array('name'=>'homeworks', 'index'=>'homeworks', 'align'=>'left', 'search' => 'true'),
array('name'=>'wikis', 'index'=>'wikis', 'align'=>'left', 'search' => 'true'),
array('name'=>'surveys', 'index'=>'surveys', 'align'=>'left', 'search' => 'true'),
//Course description
array('name'=>'course_description_progress', 'index'=>'course_description_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'lastname', 'index'=>'lastname', 'align'=>'left'),
array('name'=>'firstname', 'index'=>'firstname', 'align'=>'left'),
array('name'=>'username', 'index'=>'username', 'align'=>'left'),
#array('name'=>'profile', 'index'=>'username', 'align'=>'left'),
array('name'=>'total', 'index'=>'total', 'align'=>'left'),
array('name'=>'courses', 'index'=>'courses', 'align'=>'left', 'sortable' => 'false'),
array('name'=>'lessons', 'index'=>'lessons', 'align'=>'left', 'sortable' => 'false'),
array('name'=>'exercises', 'index'=>'exercises', 'align'=>'left', 'sortable' => 'false'),
array('name'=>'forums', 'index'=>'forums', 'align'=>'left', 'sortable' => 'false'),
array('name'=>'homeworks', 'index'=>'homeworks', 'align'=>'left', 'sortable' => 'false'),
array('name'=>'wikis', 'index'=>'wikis', 'align'=>'left', 'sortable' => 'false'),
array('name'=>'surveys', 'index'=>'surveys', 'align'=>'left', 'sortable' => 'false'),
//Lessons
array('name'=>'lessons_total', 'index'=>'lessons_total', 'align'=>'left', 'search' => 'true'),
array('name'=>'lessons_done', 'index'=>'lessons_done', 'align'=>'left', 'search' => 'true'),
array('name'=>'lessons_left', 'index'=>'lessons_left', 'align'=>'left', 'search' => 'true'),
array('name'=>'lessons_progress', 'index'=>'lessons_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'lessons_total', 'index'=>'lessons_total', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'lessons_done', 'index'=>'lessons_done', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'lessons_left', 'index'=>'lessons_left', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'lessons_progress', 'index'=>'lessons_progress', 'align'=>'center', 'sortable' => 'false'),
//Exercises
array('name'=>'exercises_total', 'index'=>'exercises_total', 'align'=>'left', 'search' => 'true'),
array('name'=>'exercises_done', 'index'=>'exercises_done', 'align'=>'left', 'search' => 'true'),
array('name'=>'exercises_left', 'index'=>'exercises_left', 'align'=>'left', 'search' => 'true'),
array('name'=>'exercises_progress', 'index'=>'exercises_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'exercises_total', 'index'=>'exercises_total', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'exercises_done', 'index'=>'exercises_done', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'exercises_left', 'index'=>'exercises_left', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'exercises_progress', 'index'=>'exercises_progress', 'align'=>'center', 'sortable' => 'false'),
//Assignments
array('name'=>'forums_total', 'index'=>'forums_total', 'align'=>'left', 'search' => 'true'),
array('name'=>'forums_done', 'index'=>'forums_done', 'align'=>'left', 'search' => 'true'),
array('name'=>'forums_left', 'index'=>'forums_left', 'align'=>'left', 'search' => 'true'),
array('name'=>'forums_progress', 'index'=>'forums_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'forums_total', 'index'=>'forums_total', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'forums_done', 'index'=>'forums_done', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'forums_left', 'index'=>'forums_left', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'forums_progress', 'index'=>'forums_progress', 'align'=>'center', 'sortable' => 'false'),
//Assignments
array('name'=>'assigments_total', 'index'=>'assigments_total', 'align'=>'left', 'search' => 'true'),
array('name'=>'assigments_done', 'index'=>'assigments_done', 'align'=>'left', 'search' => 'true'),
array('name'=>'assigments_left', 'index'=>'assigments_left', 'align'=>'left', 'search' => 'true'),
array('name'=>'assigments_progress', 'index'=>'assigments_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'assigments_total', 'index'=>'assigments_total', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'assigments_done', 'index'=>'assigments_done', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'assigments_left', 'index'=>'assigments_left', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'assigments_progress', 'index'=>'assigments_progress', 'align'=>'center', 'sortable' => 'false'),
//Assignments
array('name'=>'wiki_total', 'index'=>'wiki_total', 'align'=>'left', 'search' => 'true'),
array('name'=>'wiki_revisions', 'index'=>'wiki_revisions', 'align'=>'left', 'search' => 'true'),
array('name'=>'wiki_read', 'index'=>'wiki_read', 'align'=>'left', 'search' => 'true'),
array('name'=>'wiki_unread', 'index'=>'wiki_unread', 'align'=>'left', 'search' => 'true'),
array('name'=>'wiki_progress', 'index'=>'wiki_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'wiki_total', 'index'=>'wiki_total', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'wiki_revisions', 'index'=>'wiki_revisions', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'wiki_read', 'index'=>'wiki_read', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'wiki_unread', 'index'=>'wiki_unread', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'wiki_progress', 'index'=>'wiki_progress', 'align'=>'center', 'sortable' => 'false'),
//Surveys
array('name'=>'surveys_total', 'index'=>'surveys_total', 'align'=>'left', 'search' => 'true'),
array('name'=>'surveys_done', 'index'=>'surveys_done', 'align'=>'left', 'search' => 'true'),
array('name'=>'surveys_left', 'index'=>'surveys_left', 'align'=>'left', 'search' => 'true'),
array('name'=>'surveys_progress', 'index'=>'surveys_progress', 'align'=>'left', 'search' => 'true'),
array('name'=>'surveys_total', 'index'=>'surveys_total', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'surveys_done', 'index'=>'surveys_done', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'surveys_left', 'index'=>'surveys_left', 'align'=>'center', 'sortable' => 'false'),
array('name'=>'surveys_progress', 'index'=>'surveys_progress', 'align'=>'center', 'sortable' => 'false'),
);
$action_links = '';
// jqgrid will use this URL to do the selects
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_progress&session_id=' . intval($sessionId) . '&course_id=' . intval($courseId);
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_session_progress&session_id=' . $sessionId . '&course_id=' . $courseId . '&date_to=' . $date_to . '&date_from=' . $date_from;
//Table Id
$tableId = 'progressOverview';
@ -591,6 +707,47 @@ class MySpace {
//Autowidth
$extra_params['autowidth'] = 'true';
$extra_params['shrinkToFit'] = 'true';
$extra_params['headertitles'] = 'true';
$extra_params['groupHeaders'] = array(
'courses_detail' => array(
"startColumnName" => 'courses',
"numberOfColumns" => 7,
"titleText" => get_lang('Global'),
),
'lessons' => array(
"startColumnName" => 'lessons_total',
"numberOfColumns" => 4,
"titleText" => get_lang('LearningPaths'),
),
'exercises' => array(
"startColumnName" => 'exercises_total',
"numberOfColumns" => 4,
"titleText" => get_lang('Exercises'),
),
'forums' => array(
"startColumnName" => 'forums_total',
"numberOfColumns" => 4,
"titleText" => get_lang('Forums'),
),
'assignments' => array(
"startColumnName" => 'assigments_total',
"numberOfColumns" => 4,
"titleText" => get_lang('Assignments'),
),
'wikis' => array(
"startColumnName" => 'wiki_total',
"numberOfColumns" => 5,
"titleText" => get_lang('Wiki'),
),
'surveys' => array(
"startColumnName" => 'surveys_total',
"numberOfColumns" => 4,
"titleText" => get_lang('Survey'),
),
);
//height auto
$extra_params['height'] = 'auto';
@ -614,16 +771,17 @@ class MySpace {
* @author César Perales <cesar.perales@beeznest.com>, Beeznest Team
* @version Chamilo 1.9.6
*/
function display_tracking_access_overview($sessionId = 0, $courseId = 0, $studentId = '', $profile = '', $date_to, $date_from) {
static function display_tracking_access_overview($sessionId = 0, $courseId = 0, $studentId = '', $profile = '', $date_from, $date_to) {
//The order is important you need to check the the $column variable in the model.ajax.php file
$columns = array(
get_lang('LoginDate'),
get_lang('Username'),
get_lang('Firstname'),
get_lang('Lastname'),
get_lang('UserName'),
get_lang('LastName'),
get_lang('FirstName'),
get_lang('Clicks'),
get_lang('IP'),
get_lang('TimeLoggedIn'),
get_lang('Section'),
);
$column_model = array(
@ -634,6 +792,7 @@ class MySpace {
array('name'=>'clicks', 'index'=>'clicks', 'align'=>'left', 'search' => 'true'),
array('name'=>'ip', 'index'=>'ip', 'align'=>'left', 'search' => 'true'),
array('name'=>'timeloggedin', 'index'=>'timeLoggedIn', 'align'=>'left', 'search' => 'true'),
array('name'=>'session', 'index'=>'session', 'align'=>'left')
);
$action_links = '';

@ -170,7 +170,7 @@ class learnpathList {
* @param int Id of session
* @return array List of lessons with lessons id as keys
*/
function get_course_lessons($course_code, $session_id) {
static function get_course_lessons($course_code, $session_id) {
$tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
$course = api_get_course_info($course_code);

@ -44,7 +44,7 @@ require_once 'aiccItem.class.php';
* @param array Interactions array
* @param string Core exit SCORM string
*/
function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1, $min = -1, $status = '', $time = 0, $suspend = '', $location = '', $interactions = array(), $core_exit = 'none')
function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1, $min = -1, $status = '', $time = 0, $suspend = '', $location = '', $interactions = array(), $core_exit = 'none', $sessionId = null, $courseId = null)
{
global $debug;
$return = null;
@ -58,6 +58,9 @@ function save_item($lp_id, $user_id, $view_id, $item_id, $score = -1, $max = -1,
$mylp = null;
$lpobject = Session::read('lpobject');
if (!is_object($lpobject) && isset($sessionId) && isset($courseId)) {
$lpobject = new learnpathItem($lp_id, $user_id, $courseId);
}
if (isset($lpobject)) {
$oLP = unserialize($lpobject);
if ($debug) error_log("lpobject was set");
@ -305,5 +308,8 @@ echo save_item(
(!empty($_REQUEST['suspend'])?$_REQUEST['suspend']:null),
(!empty($_REQUEST['loc'])?$_REQUEST['loc']:null),
$interactions,
(!empty($_REQUEST['core_exit'])?$_REQUEST['core_exit']:'')
(!empty($_REQUEST['core_exit'])?$_REQUEST['core_exit']:''),
'',
(!empty($_REQUEST['session_id'])?$_REQUEST['session_id']:''),
(!empty($_REQUEST['course_id'])?$_REQUEST['course_id']:'')
);

@ -864,6 +864,12 @@ switch ($action) {
$_SESSION['oLP']->delete_lp_image();
}
$extraFieldValue = new ExtraFieldValue('lp');
$params = array(
'lp_id' => $_SESSION['oLP']->id
);
$extraFieldValue->save_field_values($_REQUEST);
if ($_FILES['lp_preview_image']['size'] > 0)
$_SESSION['oLP']->upload_image($_FILES['lp_preview_image']);

@ -23,9 +23,9 @@ if (isset($_SESSION['gradebook'])) {
if (!empty($gradebook) && $gradebook == 'view') {
$interbreadcrumb[] = array (
'url' => '../gradebook/'.$_SESSION['gradebook_dest'],
'name' => get_lang('ToolGradebook')
);
'url' => '../gradebook/'.$_SESSION['gradebook_dest'],
'name' => get_lang('ToolGradebook')
);
}
$interbreadcrumb[] = array('url' => 'lp_controller.php?action=list', 'name' => get_lang('LearningPaths'));
$interbreadcrumb[] = array('url' => api_get_self()."?action=build&lp_id=".$_SESSION['oLP']->get_id(), 'name' => $_SESSION['oLP']->get_name());
@ -50,11 +50,6 @@ function activate_end_date() {
</script>';
Display::display_header(get_lang('CourseSettings'), 'Path');
echo $_SESSION['oLP']->build_action_menu();
$gradebook = isset($_GET['gradebook']) ? Security::remove_XSS($_GET['gradebook']) : null;
$defaults=array();
@ -198,6 +193,9 @@ if (api_is_platform_admin()) {
$defaults['use_max_score'] = $_SESSION['oLP']->use_max_score;
}
$extraField = new ExtraField('lp');
$extra = $extraField->addElements($form, $_SESSION['oLP']->get_id());
//Submit button
$form->addElement('style_submit_button', 'Submit',get_lang('SaveLPSettings'),'class="save"');
@ -205,12 +203,24 @@ $form->addElement('style_submit_button', 'Submit',get_lang('SaveLPSettings'),'cl
$form->addElement('hidden', 'action', 'update_lp');
$form->addElement('hidden', 'lp_id', $_SESSION['oLP']->get_id());
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/jquery.fcbkcomplete.js" type="text/javascript" language="javascript"></script>';
$htmlHeadXtra[] = '<link href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/tag/style.css" rel="stylesheet" type="text/css" />';
$htmlHeadXtra[] ='<script>
$(function() {
'.$extra['jquery_ready_content'].'
});
</script>';
$defaults['publicated_on'] = ($publicated_on!='0000-00-00 00:00:00' && !empty($publicated_on))? api_get_local_time($publicated_on) : date('Y-m-d 12:00:00');
$defaults['expired_on'] = ($expired_on !='0000-00-00 00:00:00' && !empty($expired_on) )? api_get_local_time($expired_on): date('Y-m-d 12:00:00',time()+84600);
$form->setDefaults($defaults);
Display::display_header(get_lang('CourseSettings'), 'Path');
echo $_SESSION['oLP']->build_action_menu();
echo '<div class="row">';
if ($_SESSION['oLP']->get_hide_toc_frame() == 1) {

@ -48,7 +48,7 @@ $course_id = $course_info['real_id'];
if (isset($_GET['student_id'])) {
$student_id = intval($_GET['student_id']);
}
$session_id = api_get_session_id();
$session_id = ($_GET['id_session'])? intval($_GET['id_session']) : api_get_session_id();
$session_condition = api_get_session_condition($session_id);
//When origin is not set that means that the lp_stats are viewed from the "man running" icon
@ -859,10 +859,10 @@ if (!empty($a_my_id)) {
//var_dump($my_studen_id, $my_course_id,$a_my_id);
if (isset($_GET['extend_attempt'])) {
//"Right green cross" extended
$total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, api_get_session_id(), false, false);
$total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, $session_id, false, false);
} else {
//"Left green cross" extended
$total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, api_get_session_id(), false, true);
$total_score = Tracking::get_avg_student_score($my_studen_id, $my_course_id, $a_my_id, $session_id, false, true);
}
} else {
// Extend all "left green cross"
@ -870,12 +870,12 @@ if (!empty($a_my_id)) {
$my_course_id = Database::escape_string($_GET['course']);
// var_dump($student_id, $my_course_id );
if (!empty($student_id) && !empty($my_course_id)) {
$total_score = Tracking::get_avg_student_score($student_id, $my_course_id, array(intval($_GET['lp_id'])), api_get_session_id(), false, false);
$total_score = Tracking::get_avg_student_score($student_id, $my_course_id, array(intval($_GET['lp_id'])), $session_id, false, false);
} else {
$total_score = 0;
}
} else {
$total_score = Tracking::get_avg_student_score(api_get_user_id(), api_get_course_id(), array(intval($_GET['lp_id'])), api_get_session_id(), false, false);
$total_score = Tracking::get_avg_student_score(api_get_user_id(), api_get_course_id(), array(intval($_GET['lp_id'])), $session_id, false, false);
}
}

@ -183,8 +183,8 @@ olms.lms_item_lesson_mode = '<?php echo $oItem->get_lesson_mode();?>';
olms.lms_item_launch_data = '<?php echo addslashes($oItem->get_launch_data());?>';
olms.lms_item_core_exit = '<?php echo $oItem->get_core_exit();?>';
olms.lms_course_id = '<?php echo $oLP->get_course_int_id(); ?>';
olms.lms_session_id = '<?php echo api_get_session_id(); ?>';
olms.lms_course_code = '<?php echo $oLP->getCourseCode(); ?>';
<?php echo $oLP->get_items_details_as_js('olms.lms_item_types');?>
olms.asset_timer = 0;
@ -1498,13 +1498,31 @@ function switch_item(current_item, next_item){
* @return void
* @uses lp_ajax_save_item.php through an AJAX call
*/
function xajax_save_item(lms_lp_id, lms_user_id, lms_view_id, lms_item_id, score, max, min, lesson_status, session_time, suspend_data, lesson_location, interactions, lms_item_core_exit, item_type) {
function xajax_save_item(
lms_lp_id,
lms_user_id,
lms_view_id,
lms_item_id,
score,
max,
min,
lesson_status,
session_time,
suspend_data,
lesson_location,
interactions,
lms_item_core_exit,
item_type,
session_id,
course_id) {
var params = '';
params += 'lid='+lms_lp_id+'&uid='+lms_user_id+'&vid='+lms_view_id;
params += '&iid='+lms_item_id+'&s='+score+'&max='+max+'&min='+min;
params += '&status='+lesson_status+'&t='+session_time;
params += '&suspend='+suspend_data+'&loc='+lesson_location;
params += '&core_exit='+lms_item_core_exit;
params += '&session_id='+session_id;
params += '&course_id='+course_id;
//console.info(session_time);
if (olms.lms_lp_type == 1 || item_type == 'document') {
logit_lms('xajax_save_item with params:' + params,3);

@ -119,7 +119,16 @@ if (!empty($course_list)) {
true
);
$lp_list = $list->get_flat_list();
$lp_count = count($lp_list);
$lp_count = 0;
if(!empty($lp_list)) {
foreach ($lp_list as $valLp) {
if($valLp['lp_visibility']) {
$lp_count++;
}
}
}
$course_info = api_get_course_info($course_data['code']);
$exercise_count = count(get_all_exercises($course_info, $session_id, true));

Loading…
Cancel
Save