tpl update skill

1.10.x
aragonc 11 years ago
commit 1ccf25ae33
  1. 55
      README.md
  2. 17
      composer.lock
  3. 1
      main/attendance/attendance_calendar.php
  4. 40
      main/attendance/attendance_controller.php
  5. 15
      main/attendance/attendance_list.php
  6. 53
      main/attendance/index.php
  7. 82
      main/coursecopy/classes/CourseRestorer.class.php
  8. 4
      main/cron/create_course_sessions.php
  9. 132
      main/cron/remind_course_expiration.php
  10. 10
      main/gradebook/gradebook_flatview.php
  11. 3
      main/gradebook/gradebook_view_result.php
  12. 2
      main/gradebook/index.php
  13. 25
      main/gradebook/lib/be/abstractlink.class.php
  14. 63
      main/gradebook/lib/be/attendancelink.class.php
  15. 203
      main/gradebook/lib/be/category.class.php
  16. 45
      main/gradebook/lib/be/evaluation.class.php
  17. 34
      main/gradebook/lib/be/exerciselink.class.php
  18. 36
      main/gradebook/lib/be/forumthreadlink.class.php
  19. 20
      main/gradebook/lib/be/learnpathlink.class.php
  20. 5
      main/gradebook/lib/be/result.class.php
  21. 20
      main/gradebook/lib/be/studentpublicationlink.class.php
  22. 36
      main/gradebook/lib/be/surveylink.class.php
  23. 242
      main/gradebook/lib/fe/gradebooktable.class.php
  24. 4
      main/gradebook/lib/flatview_data_generator.class.php
  25. 164
      main/gradebook/lib/gradebook_data_generator.class.php
  26. 38
      main/gradebook/lib/scoredisplay.class.php
  27. 98
      main/gradebook/lib/user_data_generator.class.php
  28. 115
      main/inc/lib/attendance.lib.php
  29. 281
      main/inc/lib/course.lib.php
  30. 8
      main/inc/lib/sessionmanager.lib.php
  31. 12
      main/inc/lib/social.lib.php
  32. 13
      main/install/configuration.dist.php
  33. 4
      main/install/db_main.sql
  34. 6
      main/lang/english/trad4all.inc.php
  35. 23
      main/lang/french/trad4all.inc.php
  36. 7
      main/lang/spanish/trad4all.inc.php
  37. 26
      main/newscorm/lp_controller.php
  38. 20
      main/newscorm/scorm_api.php
  39. 6
      main/template/default/skill/skill_wheel.tpl
  40. 6
      main/template/default/skill/skill_wheel_student.tpl
  41. 8
      plugin/buycourses/src/buy_course.lib.php
  42. 202
      tests/scripts/course2session.php

@ -2,9 +2,36 @@
## Installation
This installation guide is for development environments only.
### Install PHP, a web server and MySQL/MariaDB
To run Chamilo, you will need at least a web server (we recommend Apache2 for commodity reasons), a database server (we recommend MariaDB but will explain MySQL for commodity reasons) and a PHP interpreter (and a series of libraries for it). If you are working on a Debian-based system (Debian, Ubuntu, Mint, etc), just
type
```
sudo apt-get install libapache2-mod-php mysql-server php5-gd php5-intl php5-curl php5-json
```
### Install Git
The development version 1.10.x requires you to have Git installed. If you are working on a Debian-based system (Debian, Ubuntu, Mint, etc), just type
```
sudo apt-get install git
```
### Install Composer
To run the development version 1.10.x, you need Composer, a libraries dependency management system that will update all the libraries you need for Chamilo to the latest available version.
Make sure you have Composer installed. If you do, you should be able to launch "composer" on the command line and have the inline help of composer show a few subcommands. If you don't, please follow the installation guide at https://getcomposer.org/download/
### Download Chamilo from GitHub
Clone the repository
```
sudo mkdir chamilo-1.10
sudo chown -R `whoami` chamilo-1.10
git clone https://github.com/chamilo/chamilo-lms.git chamilo-1.10
```
@ -16,11 +43,37 @@ git checkout --track origin/1.10.x
git config --global push.default current
```
Update dependencies using Composer
### Update dependencies using Composer
From the Chamilo folder (in which you should be now if you followed the previous steps), launch:
```
composer update
```
### Change permissions
On a Debian-based system, launch:
```
sudo chown -R www-data:www-data archive course data home searchdb main/upload/users main/upload/sessions main/upload/courses main/default_course_document/images main/lang main/css main/inc/conf
```
### Start the installer
In your browser, load the Chamilo URL. You should be automatically redirected to the installer. If not, add the "main/install/index.php" suffix manually in your browser address bar. The rest should be a matter of simple OK > Next > OK > Next...
## Upgrade from 1.9.x
1.10.x is a major version. As such, it contains a series of new features, that also mean a series of new database changes in regards with versions 1.9.x. As such, it is necessary to go through an upgrade procedure when upgrading from 1.9.x to 1.10.x.
Although 1.10.x is not beta yet (and as such is *NOT* ready for production and does *NOT* contain all database changes yet - DO NOT UPGRADE A PRODUCTION SYSTEM to 1.10.x yet, PLEASE!), the upgrade procedure works to get you up and running with the latest *development* code of 1.10.x with data from an 1.9.x system, so feel free to test it out, but keep a backup of your database from 1.9.x as you will need to do the upgrade again each time you are updating the 1.10.x code from Git.
The upgrade procedure is relatively straightforward. If you have a 1.9.x initially installed with Git, here are the steps you should follow (considering you are already inside the Chamilo folder):
```
git fetch --all
git checkout origin 1.10.x
```
Then load the Chamilo URL in your browser, adding "main/install/index.php" and follow the upgrade instructions. Select the "Upgrade from 1.8.x" button to proceed.
# Documentation
For more information on Chamilo, visit https://stable.chamilo.org/documentation

17
composer.lock generated

@ -1365,16 +1365,16 @@
},
{
"name": "monolog/monolog",
"version": "1.12.0",
"version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "1fbe8c2641f2b163addf49cc5e18f144bec6b19f"
"reference": "c41c218e239b50446fd883acb1ecfd4b770caeae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/1fbe8c2641f2b163addf49cc5e18f144bec6b19f",
"reference": "1fbe8c2641f2b163addf49cc5e18f144bec6b19f",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/c41c218e239b50446fd883acb1ecfd4b770caeae",
"reference": "c41c218e239b50446fd883acb1ecfd4b770caeae",
"shasum": ""
},
"require": {
@ -1391,6 +1391,7 @@
"phpunit/phpunit": "~4.0",
"raven/raven": "~0.5",
"ruflin/elastica": "0.90.*",
"swiftmailer/swiftmailer": "~5.3",
"videlalvaro/php-amqplib": "~2.4"
},
"suggest": {
@ -1407,7 +1408,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.12.x-dev"
"dev-master": "1.13.x-dev"
}
},
"autoload": {
@ -1433,19 +1434,19 @@
"logging",
"psr-3"
],
"time": "2014-12-29 21:29:35"
"time": "2015-03-05 01:12:12"
},
{
"name": "mpdf/mpdf",
"version": "v5.7.4",
"source": {
"type": "git",
"url": "https://github.com/finwe/mpdf.git",
"url": "https://github.com/mpdf/mpdf.git",
"reference": "f9a374c7ea975ce8c795cec4dfd17ef55addac9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/finwe/mpdf/zipball/f9a374c7ea975ce8c795cec4dfd17ef55addac9c",
"url": "https://api.github.com/repos/mpdf/mpdf/zipball/f9a374c7ea975ce8c795cec4dfd17ef55addac9c",
"reference": "f9a374c7ea975ce8c795cec4dfd17ef55addac9c",
"shasum": ""
},

@ -130,7 +130,6 @@ if (isset($action) && $action == 'calendar_add') {
Display::return_icon('delete.png', get_lang('Delete'), array('style'=>'vertical-align:middle'), ICON_SIZE_SMALL).'</a>';
echo '</span>';
}
}
}
echo '</div>';

@ -156,6 +156,11 @@ class AttendanceController
*/
public function attendance_delete($attendance_id)
{
$allowDeleteAttendance = api_get_configuration_value('allow_delete_attendance');
if ($allowDeleteAttendance == false) {
$this->attendance_list();
return false;
}
$attendance = new Attendance();
if (!empty($attendance_id)) {
$affected_rows = $attendance->attendance_delete($attendance_id);
@ -166,6 +171,41 @@ class AttendanceController
$this->attendance_list();
}
/**
* It's used for make attendance visible
* render to attendance_list view
* @param int attendance id
*/
public function attendanceSetVisible($attendanceId)
{
$attendance = new Attendance();
if (!empty($attendanceId)) {
$affectedRows = $attendance->changeVisibility($attendanceId, 1);
}
if ($affectedRows) {
$message['message_attendance_delete'] = true;
}
$this->attendance_list();
}
/**
* It's used for make attendance invisible
* render to attendance_list view
* @param int attendance id
*/
public function attendanceSetInvisible($attendanceId)
{
$attendance = new Attendance();
if (!empty($attendanceId)) {
$affectedRows = $attendance->changeVisibility($attendanceId, 0);
}
if ($affectedRows) {
$message['message_attendance_delete'] = true;
}
$this->attendance_list();
}
/**
* Restores an attendance entry and fallback to attendances rendering
* @param int attendance id

@ -18,10 +18,6 @@ if (api_is_allowed_to_edit(null, true)) {
echo '<div class="actions">';
echo '<a href="index.php?'.api_get_cidreq().$param_gradebook.'&action=attendance_add">'.
Display::return_icon('new_attendance_list.png',get_lang('CreateANewAttendance'),'',ICON_SIZE_MEDIUM).'</a>';
/*echo '<a href="index.php?'.api_get_cidreq().$param_gradebook.'&action=calendar_logins">'.
Display::return_icon('attendance_list.png',get_lang('Logins'),'',ICON_SIZE_MEDIUM).'</a>';*/
echo '</div>';
}
$attendance = new Attendance();
@ -46,7 +42,16 @@ $table->set_header(3, get_lang('CountDoneAttendance'), true, array('style'=>'wid
if (api_is_allowed_to_edit(null, true)) {
$table->set_header(4, get_lang('Actions'), false, array('style'=>'text-align:center'));
$table->set_form_actions(array ('attendance_delete_select' => get_lang('DeleteAllSelectedAttendances')));
$actions = array(
'attendance_set_invisible_select' => get_lang('SetInvisible'),
'attendance_set_visible_select' => get_lang('SetVisible')
);
$allow = api_get_configuration_value('allow_delete_attendance');
if ($allow) {
$actions['attendance_delete_select'] = get_lang('DeleteAllSelectedAttendances');
}
$table->set_form_actions($actions);
}
if ($table->get_total_number_of_items() > 0) {

@ -41,6 +41,10 @@ $actions = array(
'attendance_edit',
'attendance_delete',
'attendance_delete_select',
'attendance_set_invisible',
'attendance_set_invisible_select',
'attendance_set_visible',
'attendance_set_visible_select',
'attendance_restore',
'attendance_sheet_export_to_pdf',
'attendance_sheet_list_no_edit',
@ -228,11 +232,20 @@ if ($action == 'calendar_add') {
$interbreadcrumb[] = array('url' => '#', 'name' => get_lang('AddDateAndTime'));
}
// delete selected attendance
// Delete selected attendance
if (isset($_POST['action']) && $_POST['action'] == 'attendance_delete_select') {
$attendanceController->attendance_delete($_POST['id']);
}
// distpacher actions to controller
if (isset($_POST['action']) && $_POST['action'] == 'attendance_set_invisible_select') {
$attendanceController->attendanceSetInvisible($_POST['id']);
}
if (isset($_POST['action']) && $_POST['action'] == 'attendance_set_visible_select') {
$attendanceController->attendanceSetVisible($_POST['id']);
}
// Distpacher actions to controller
switch ($action) {
case 'attendance_list':
$attendanceController->attendance_list();
@ -244,27 +257,41 @@ switch ($action) {
api_not_allowed();
}
break;
case 'attendance_edit' :
case 'attendance_edit':
if (api_is_allowed_to_edit(null, true)) {
$attendanceController->attendance_edit($attendance_id);
} else {
api_not_allowed();
}
break;
case 'attendance_delete' :
case 'attendance_delete':
if (api_is_allowed_to_edit(null, true)) {
$attendanceController->attendance_delete($attendance_id);
} else {
api_not_allowed();
}
break;
case 'attendance_restore':
case 'attendance_set_invisible':
if (api_is_allowed_to_edit(null, true)) {
$attendanceController->attendance_restore($attendance_id);
$attendanceController->attendanceSetInvisible($attendance_id);
} else {
api_not_allowed();
}
break;
case 'attendance_set_visible':
if (api_is_allowed_to_edit(null, true)) {
$attendanceController->attendanceSetVisible($attendance_id);
} else {
api_not_allowed();
}
break;
/*case 'attendance_restore':
if (api_is_allowed_to_edit(null, true)) {
$attendanceController->attendance_restore($attendance_id);
} else {
api_not_allowed();
}
break;*/
case 'attendance_sheet_list':
$attendanceController->attendance_sheet($action, $attendance_id, $student_id, true);
break;
@ -281,22 +308,22 @@ switch ($action) {
api_not_allowed();
}
break;
case 'lock_attendance' :
case 'unlock_attendance' :
case 'lock_attendance':
case 'unlock_attendance':
if (api_is_allowed_to_edit(null, true)) {
$attendanceController->lock_attendance($action, $attendance_id);
} else {
api_not_allowed();
}
break;
case 'calendar_add' :
case 'calendar_edit' :
case 'calendar_all_delete' :
case 'calendar_delete' :
case 'calendar_add':
case 'calendar_edit':
case 'calendar_all_delete':
case 'calendar_delete':
if (!api_is_allowed_to_edit(null, true)) {
api_not_allowed();
}
case 'calendar_list' :
case 'calendar_list':
$attendanceController->attendance_calendar($action, $attendance_id, $calendar_id);
break;
case 'calendar_logins':

@ -889,7 +889,7 @@ class CourseRestorer
foreach ($resources[RESOURCE_FORUM] as $id => $forum) {
$params = (array)$forum->obj;
if ($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id == -1) {
$cat_id = $this->restore_forum_category($params['forum_category']);
$cat_id = $this->restore_forum_category($params['forum_category'], $sessionId);
} else {
$cat_id = $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id;
}
@ -924,7 +924,7 @@ class CourseRestorer
if (is_array($this->course->resources[RESOURCE_FORUMTOPIC])) {
foreach ($this->course->resources[RESOURCE_FORUMTOPIC] as $topic_id => $topic) {
if ($topic->obj->forum_id == $id) {
$this->restore_topic($topic_id, $new_id);
$this->restore_topic($topic_id, $new_id, $sessionId);
$forum_topics ++;
}
}
@ -941,7 +941,7 @@ class CourseRestorer
/**
* Restore forum-categories
*/
public function restore_forum_category($my_id = null)
public function restore_forum_category($my_id = null, $sessionId = 0)
{
$forum_cat_table = Database :: get_course_table(TABLE_FORUM_CATEGORY);
$resources = $this->course->resources;
@ -964,7 +964,14 @@ class CourseRestorer
}
$params = (array) $forum_cat->obj;
$params['c_id'] = $this->destination_course_id;
$params['cat_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($params['cat_comment'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
$params['cat_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
$params['cat_comment'],
$this->course->code,
$this->course->destination_path,
$this->course->backup_path,
$this->course->info['path']
);
$params['session_id'] = intval($sessionId);
unset($params['cat_id']);
$params = self::DBUTF8_array($params);
$new_id = Database::insert($forum_cat_table, $params);
@ -980,14 +987,14 @@ class CourseRestorer
/**
* Restore a forum-topic
*/
public function restore_topic($thread_id, $forum_id)
public function restore_topic($thread_id, $forum_id, $sessionId = 0)
{
$table = Database :: get_course_table(TABLE_FORUM_THREAD);
$topic = $this->course->resources[RESOURCE_FORUMTOPIC][$thread_id];
$params = (array)$topic->obj;
$params = self::DBUTF8_array($params);
$params['c_id'] = $this->destination_course_id;
$params['c_id'] = $this->destination_course_id;
$params['forum_id'] = $forum_id;
$params['thread_poster_id'] = $this->first_teacher_id;
$params['thread_date'] = api_get_utc_datetime();
@ -995,19 +1002,31 @@ class CourseRestorer
$params['thread_last_post'] = 0;
$params['thread_replies'] = 0;
$params['thread_views'] = 0;
$params['session_id'] = intval($sessionId);
unset($params['thread_id']);
$new_id = Database::insert($table, $params);
api_item_property_update($this->destination_course_info, TOOL_FORUM_THREAD, $new_id, 'ThreadAdded', api_get_user_id(), 0, 0, null, null);
api_item_property_update(
$this->destination_course_info,
TOOL_FORUM_THREAD,
$new_id,
'ThreadAdded',
api_get_user_id(),
0,
0,
null,
null,
$sessionId
);
$this->course->resources[RESOURCE_FORUMTOPIC][$thread_id]->destination_id = $new_id;
$topic_replies = -1;
foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post){
foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post) {
if ($post->obj->thread_id == $thread_id) {
$topic_replies++;
$this->restore_post($post_id, $new_id, $forum_id);
$this->restore_post($post_id, $new_id, $forum_id, $sessionId);
}
}
return $new_id;
@ -1017,7 +1036,7 @@ class CourseRestorer
* Restore a forum-post
* @TODO Restore tree-structure of posts. For example: attachments to posts.
*/
public function restore_post($id, $topic_id, $forum_id)
public function restore_post($id, $topic_id, $forum_id, $sessionId = 0)
{
$table_post = Database :: get_course_table(TABLE_FORUM_POST);
$post = $this->course->resources[RESOURCE_FORUMPOST][$id];
@ -1028,9 +1047,26 @@ class CourseRestorer
$params['poster_id'] = $this->first_teacher_id;
$params['post_date'] = api_get_utc_datetime();
unset($params['post_id']);
$params['post_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course($params['post_text'], $this->course->code, $this->course->destination_path, $this->course->backup_path, $this->course->info['path']);
$params['post_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
$params['post_text'],
$this->course->code,
$this->course->destination_path,
$this->course->backup_path,
$this->course->info['path']
);
$new_id = Database::insert($table_post, $params);
api_item_property_update($this->destination_course_info, TOOL_FORUM_POST, $new_id, 'PostAdded', api_get_user_id(), 0, 0, null, null);
api_item_property_update(
$this->destination_course_info,
TOOL_FORUM_POST,
$new_id,
'PostAdded',
api_get_user_id(),
0,
0,
null,
null,
$sessionId
);
$this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id;
return $new_id;
}
@ -1045,7 +1081,8 @@ class CourseRestorer
$resources = $this->course->resources;
foreach ($resources[RESOURCE_LINK] as $id => $link) {
$cat_id = $this->restore_link_category($link->category_id, $session_id);
$sql = "SELECT MAX(display_order) FROM $link_table WHERE c_id = ".$this->destination_course_id." AND category_id='" . self::DBUTF8escapestring($cat_id). "'";
$sql = "SELECT MAX(display_order) FROM $link_table
WHERE c_id = ".$this->destination_course_id." AND category_id='" . self::DBUTF8escapestring($cat_id). "'";
$result = Database::query($sql);
list($max_order) = Database::fetch_array($result);
@ -1055,13 +1092,13 @@ class CourseRestorer
}
$sql = "INSERT INTO ".$link_table." SET
c_id = ".$this->destination_course_id." ,
url = '".self::DBUTF8escapestring($link->url)."',
title = '".self::DBUTF8escapestring($link->title)."',
description = '".self::DBUTF8escapestring($link->description)."',
category_id = '".$cat_id."',
on_homepage = '".$link->on_homepage."',
display_order = '".($max_order+1)."' $condition_session";
c_id = ".$this->destination_course_id." ,
url = '".self::DBUTF8escapestring($link->url)."',
title = '".self::DBUTF8escapestring($link->title)."',
description = '".self::DBUTF8escapestring($link->description)."',
category_id = '".$cat_id."',
on_homepage = '".$link->on_homepage."',
display_order = '".($max_order+1)."' $condition_session";
Database::query($sql);
$this->course->resources[RESOURCE_LINK][$id]->destination_id = Database::insert_id();
@ -2632,14 +2669,15 @@ class CourseRestorer
api_get_user_id(),
$this->destination_course_info,
0,
0
$sessionId
);
} else {
$workId = $workData['id'];
updateWork(
$workId,
$obj->params,
$this->destination_course_info
$this->destination_course_info,
$sessionId
);
updatePublicationAssignment(
$workId,

@ -80,9 +80,9 @@ if (!$lastingAdministrators) {
$administratorId = intval($administrators[$lastingAdministrators - 1]['user_id']);
// Creates course sessions for the current month
$dates = getMonthFirstAndLastDates();
$dates = getMonthFirstAndLastDates(date('Y-m-').'01');
// Get courses that don't have any session
$courses = CourseManager::getCoursesWithoutSession();
$courses = CourseManager::getCoursesWithoutSession($dates['startDate'], $dates['endDate']);
createCourseSessions($courses, $administratorId, $dates['startDate'], $dates['endDate']);
// Creates course sessions for the following month

@ -0,0 +1,132 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Course expiration reminder.
* @package chamilo.cron
* @author Imanol Losada <imanol.losada@beeznest.com>
*/
require_once __DIR__ . '/../inc/global.inc.php';
/**
* Initialization
*/
if (php_sapi_name() != 'cli') {
exit; //do not run from browser
}
// Days before expiration date to send reminders
define("OFFSET", 2);
$today = gmdate("Y-m-d");
$expirationDate = gmdate("Y-m-d", strtotime($today." + ".OFFSET." day"));
$query = "SELECT DISTINCT category.session_id, certificate.user_id FROM ".
Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY)." AS category
LEFT JOIN ".Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE).
" AS certificate ON category.id = certificate.cat_id
INNER JOIN ".Database::get_main_table(TABLE_MAIN_SESSION).
" AS session ON category.session_id = session.id
WHERE session.date_end BETWEEN '$today' AND '$expirationDate' AND category.session_id IS NOT NULL";
$sessionId = 0;
$userIds = array();
$sessions = array();
$result = Database::query($query);
while ($row = Database::fetch_array($result)) {
if ($sessionId != $row['session_id']) {
$sessionId = $row['session_id'];
$userIds = array();
}
if (!is_null($row['user_id'])) {
array_push($userIds, $row['user_id']);
}
$sessions[$sessionId] = $userIds;
}
$usersToBeReminded = array();
foreach ($sessions as $sessionId => $userIds) {
$userId = 0;
$userIds = $userIds ? " AND id_user NOT IN (".implode(",", $userIds).")" : null;
$query = "SELECT sessionUser.id_session, sessionUser.id_user, session.name, session.date_end FROM ".
Database::get_main_table(TABLE_MAIN_SESSION_USER)." AS sessionUser
INNER JOIN ".Database::get_main_table(TABLE_MAIN_SESSION).
" AS session ON sessionUser.id_session = session.id
WHERE id_session = $sessionId$userIds";
$result = Database::query($query);
while ($row = Database::fetch_array($result)) {
$usersToBeReminded[$row['id_user']][$row['id_session']] =
array(
'name' => $row['name'],
'date_end' => $row['date_end']
);
}
}
if ($usersToBeReminded) {
$today = date_create($today);
$platformLanguage = api_get_setting("platformLanguage");
$subject = sprintf(
get_lang("MailCronCourseExpirationReminderSubject", null, $platformLanguage),
api_get_setting("Institution")
);
$administrator = array(
'completeName' => api_get_person_name(
api_get_setting("administratorName"),
api_get_setting("administratorSurname"),
null,
PERSON_NAME_EMAIL_ADDRESS
),
'email' => api_get_setting("emailAdministrator")
);
echo "\n======================================================================\n\n";
foreach ($usersToBeReminded as $userId => $sessions) {
$user = api_get_user_info($userId);
$userCompleteName = api_get_person_name(
$user['firstname'],
$user['lastname'],
null,
PERSON_NAME_EMAIL_ADDRESS
);
foreach ($sessions as $sessionId => $session) {
$daysRemaining = date_diff($today, date_create($session['date_end']));
$join = " INNER JOIN ".Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION)."ON id = access_url_id";
$result = Database::select(
'url',
Database::get_main_table(TABLE_MAIN_ACCESS_URL).$join,
array(
'where' => array(
'session_id = ?' => array(
$sessionId
)
),
'limit' => '1'
)
);
$body = sprintf(
get_lang('MailCronCourseExpirationReminderBody', null, $platformLanguage),
$userCompleteName,
$session['name'],
$session['date_end'],
$daysRemaining->format("%d"),
$result[0]['url'],
api_get_setting("siteName")
);
api_mail_html(
$userCompleteName,
$user['email'],
$subject,
$body,
$administrator['completeName'],
$administrator['email']
);
echo "Email sent to $userCompleteName (".$user['email'].")\n";
echo "Session: ".$session['name']."\n";
echo "Date end: ".$session['date_end']."\n";
echo "Days remaining: ".$daysRemaining->format("%d")."\n\n";
}
echo "======================================================================\n\n";
}
} else {
echo "No users to be reminded\n";
}

@ -97,6 +97,11 @@ if (!empty($keyword)) {
}
$offset = isset($_GET['offset']) ? $_GET['offset'] : '0';
$addparams = array('selectcat' => $cat[0]->get_id());
if (isset($_GET['search'])) {
$addparams['search'] = $keyword;
}
// Main course category
$mainCourseCategory = Category::load(
null,
@ -237,11 +242,6 @@ if (!empty($_GET['export_report']) && $_GET['export_report'] == 'export_report')
}
}
$addparams = array ('selectcat' => $cat[0]->get_id());
if (isset($_GET['search'])) {
$addparams['search'] = $keyword;
}
$this_section = SECTION_COURSES;
if (isset($_GET['exportpdf'])) {

@ -85,7 +85,7 @@ if (isset($_GET['editres'])) {
exit;
}
}
$file_type = null;
if (isset($_GET['import'])) {
$interbreadcrumb[] = array('url' => 'gradebook_view_result.php?selecteval=' . Security::remove_XSS($_GET['selecteval']), 'name' => get_lang('ViewResult'));
$import_result_form = new DataForm(
@ -101,7 +101,6 @@ if (isset($_GET['import'])) {
}
$eval[0]->check_lock_permissions();
if ($_POST['formSent']) {
if (!empty($_FILES['import_file']['name'])) {
$values = $import_result_form->exportValues();

@ -6,7 +6,7 @@
* @package chamilo.gradebook
*/
$language_file = array('gradebook', 'exercice');
$language_file = array('gradebook', 'exercice', 'tracking');
// $cidReset : This is the main difference with gradebook.php, here we say,
// basically, that we are inside a course, and many things depend from that

@ -521,4 +521,29 @@ abstract class AbstractLink implements GradebookItem
$sql = "UPDATE $table SET locked = '".intval($locked)."' WHERE id='".$this->id."'";
Database::query($sql);
}
/**
* Get current user ranking
* @param array $studentList Array with user id and scores
* Example: [1 => 5.00, 2 => 8.00]
*/
public static function getCurrentUserRanking($studentList)
{
$ranking = null;
$currentUserId = api_get_user_id();
if (!empty($studentList) && !empty($currentUserId)) {
asort($studentList);
$ranking = $count = count($studentList);
foreach ($studentList as $userId => $position) {
if ($currentUserId == $userId) {
break;
}
$ranking--;
}
return array($ranking, $count);
}
return array();
}
}

@ -131,7 +131,10 @@ class AttendanceLink extends AbstractLink
// get attendance qualify max
$sql = 'SELECT att.attendance_qualify_max FROM '.$this->get_attendance_table().' att
WHERE att.c_id = '.$this->course_id.' AND att.id = '.intval($this->get_ref_id()).' AND att.session_id='.intval($session_id).'';
WHERE
att.c_id = '.$this->course_id.' AND
att.id = '.intval($this->get_ref_id()).' AND
att.session_id='.intval($session_id).'';
$query = Database::query($sql);
$attendance = Database::fetch_array($query);
@ -175,23 +178,29 @@ class AttendanceLink extends AbstractLink
if ($rescount == 0) {
return null;
} else {
if ($type == 'best') {
return array($bestResult, $weight);
switch ($type) {
case 'best':
return array($bestResult, $weight);
break;
case 'average':
return array($sumResult / $rescount, $weight);
break;
case 'ranking':
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($sum, $rescount);
break;
}
if ($type == 'average') {
return array($sumResult/$rescount, $weight);
}
return array($sum , $rescount);
}
}
}
// INTERNAL FUNCTIONS
/**
* Lazy load function to get the database table of the student publications
*/
private function get_attendance_table() {
private function get_attendance_table()
{
$this->attendance_table = Database :: get_course_table(TABLE_ATTENDANCE);
return $this->attendance_table;
}
@ -199,19 +208,24 @@ class AttendanceLink extends AbstractLink
/**
* Lazy load function to get the database table of the item properties
*/
private function get_itemprop_table () {
private function get_itemprop_table()
{
$this->itemprop_table = Database :: get_course_table(TABLE_ITEM_PROPERTY);
return $this->itemprop_table;
}
public function needs_name_and_description() {
public function needs_name_and_description()
{
return false;
}
public function needs_max() {
public function needs_max()
{
return false;
}
public function needs_results() {
public function needs_results()
{
return false;
}
@ -227,13 +241,16 @@ class AttendanceLink extends AbstractLink
}
}
public function get_description() {
public function get_description()
{
return '';
}
/**
* Check if this still links to an exercise
*/
public function is_valid_link() {
public function is_valid_link()
{
$session_id = api_get_session_id();
$sql = 'SELECT count(att.id) FROM '.$this->get_attendance_table().' att
WHERE att.c_id = '.$this->course_id.' AND att.id = '.intval($this->get_ref_id()).' ';
@ -242,23 +259,26 @@ class AttendanceLink extends AbstractLink
return ($number[0] != 0);
}
public function get_test_id() {
public function get_test_id()
{
return 'DEBUG:ID';
}
public function get_link() {
public function get_link()
{
//it was extracts the attendance id
$session_id = api_get_session_id();
$sql = 'SELECT * FROM '.$this->get_attendance_table().' att
WHERE att.c_id = '.$this->course_id.' AND att.id = '.intval($this->get_ref_id()).' ';
$result = Database::query($sql);
$row = Database::fetch_array($result,'ASSOC');
$row = Database::fetch_array($result,'ASSOC');
$attendance_id = $row['id'];
$url = api_get_path(WEB_PATH).'main/attendance/index.php?action=attendance_sheet_list&gradebook=view&attendance_id='.$attendance_id.'&session_id='.$session_id.'&cidReq='.$this->get_course_code();
return $url;
}
private function get_attendance_data() {
private function get_attendance_data()
{
$tbl_name = $this->get_attendance_table();
$session_id = api_get_session_id();
if ($tbl_name == '') {
@ -272,7 +292,8 @@ class AttendanceLink extends AbstractLink
return $this->attendance_data;
}
public function get_icon_name() {
public function get_icon_name()
{
return 'attendance';
}
}

@ -22,30 +22,48 @@ class Category implements GradebookItem
private $grade_model_id;
private $generateCertificates;
/**
* Consctructor
*/
public function __construct()
{
}
/**
* @return int
*/
public function get_id()
{
return $this->id;
}
/**
* @return string
*/
public function get_name()
{
return $this->name;
}
/**
* @return string
*/
public function get_description()
{
return $this->description;
}
/**
* @return int
*/
public function get_user_id()
{
return $this->user_id;
}
/**
* @return float
*/
public function get_certificate_min_score()
{
if (!empty($this->certificate_min_score)) {
@ -63,56 +81,89 @@ class Category implements GradebookItem
return $this->course_code;
}
/**
* @return mixed
*/
public function get_parent_id()
{
return $this->parent;
}
/**
* @return mixed
*/
public function get_weight()
{
return $this->weight;
}
/**
* @return bool
*/
public function is_locked()
{
return isset($this->locked) && $this->locked == 1 ? true : false;
}
/**
* @return mixed
*/
public function is_visible()
{
return $this->visible;
}
/**
* @param int $id
*/
public function set_id($id)
{
$this->id = $id;
}
/**
* @param string $name
*/
public function set_name($name)
{
$this->name = $name;
}
/**
* @param string $description
*/
public function set_description($description)
{
$this->description = $description;
}
/**
* @param int $user_id
*/
public function set_user_id($user_id)
{
$this->user_id = $user_id;
}
/**
* @param string $course_code
*/
public function set_course_code($course_code)
{
$this->course_code = $course_code;
}
public function set_certificate_min_score ($min_score = null)
/**
* @param float $min_score
*/
public function set_certificate_min_score($min_score = null)
{
$this->certificate_min_score = $min_score;
}
/**
* @param int $parent
*/
public function set_parent_id($parent)
{
$this->parent = intval($parent);
@ -157,6 +208,10 @@ class Category implements GradebookItem
return 'category';
}
/**
* @param bool $from_db
* @return array|resource
*/
public function get_skills($from_db = true)
{
if ($from_db) {
@ -170,6 +225,9 @@ class Category implements GradebookItem
return $skills;
}
/**
* @return array
*/
public function get_skills_for_select()
{
$skills = $this->get_skills();
@ -249,7 +307,8 @@ class Category implements GradebookItem
* @param int $parent_id parent category
* @param bool $visible
* @param int $session_id (in case we are in a session)
* @param bool $order_by Whether to show all "session" categories (true) or hide them (false) in case there is no session id
* @param bool $order_by Whether to show all "session"
* categories (true) or hide them (false) in case there is no session id
*/
public static function load(
$id = null,
@ -522,7 +581,9 @@ class Category implements GradebookItem
{
$tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = 'UPDATE '.$tbl_grade_categories." SET name = '".Database::escape_string($this->get_name())."'".', description = ';
$sql = 'UPDATE '.$tbl_grade_categories." SET
name = '".Database::escape_string($this->get_name())."'".',
description = ';
if (isset($this->description)) {
$sql .= "'".Database::escape_string($this->get_description())."'";
} else {
@ -604,7 +665,7 @@ class Category implements GradebookItem
* Update link weights see #5168
* @param type $new_weight
*/
function update_children_weight($new_weight)
public function update_children_weight($new_weight)
{
$links = $this->get_links();
$old_weight = $this->get_weight();
@ -636,7 +697,8 @@ class Category implements GradebookItem
public function update_category_delete($course_id)
{
$tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = 'UPDATE '.$tbl_grade_categories.' SET visible=3 WHERE course_code ="'.Database::escape_string($course_id).'"';
$sql = 'UPDATE '.$tbl_grade_categories.' SET visible=3
WHERE course_code ="'.Database::escape_string($course_id).'"';
Database::query($sql);
}
@ -668,7 +730,9 @@ class Category implements GradebookItem
return null;
} else {
$tbl_category = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql='SELECT name,description,user_id,course_code,parent_id,weight,visible,certif_min_score,session_id, generate_certificates FROM '.$tbl_category.' c WHERE c.id='.intval($selectcat);
$sql = 'SELECT name,description,user_id,course_code,parent_id,weight,visible,certif_min_score,session_id, generate_certificates
FROM '.$tbl_category.' c
WHERE c.id='.intval($selectcat);
$result = Database::query($sql);
$row = Database::fetch_array($result, 'ASSOC');
@ -727,7 +791,7 @@ class Category implements GradebookItem
*/
public function is_certificate_available($user_id)
{
$score = $this->calc_score($user_id, $this->course_code);
$score = $this->calc_score($user_id, null, $this->course_code);
if (isset($score) && isset($score[0])) {
// Get a percentage score to compare to minimum certificate score
@ -760,8 +824,12 @@ class Category implements GradebookItem
* @return array (score sum, weight sum)
* or null if no scores available
*/
public function calc_score($stud_id = null, $course_code = '', $session_id = null)
{
public function calc_score(
$stud_id = null,
$type = null,
$course_code = '',
$session_id = null
) {
// Get appropriate subcategories, evaluations and links
if (!empty($course_code)) {
$cats = $this->get_subcategories($stud_id, $course_code, $session_id);
@ -773,22 +841,32 @@ class Category implements GradebookItem
$links = $this->get_links($stud_id);
}
// calculate score
$rescount = 0;
$ressum = 0;
// Calculate score
$rescount = 0;
$ressum = 0;
$weightsum = 0;
$bestResult = 0;
$students = [];
if (!empty($cats)) {
/** @var Category $cat */
foreach ($cats as $cat) {
$catres = $cat->calc_score($stud_id, $course_code, $session_id);
$score = $cat->calc_score(
$stud_id,
$type,
$course_code,
$session_id
);
if ($cat->get_weight() != 0) {
$catweight = $cat->get_weight();
$rescount++;
$weightsum += $catweight;
}
if (isset($catres)) {
$ressum += (($catres[0]/$catres[1]) * $catweight);
if (isset($score)) {
$ressum += $score[0]/$score[1] * $catweight;
$bestResult += $ressum;
}
}
}
@ -796,13 +874,16 @@ class Category implements GradebookItem
if (!empty($evals)) {
/** @var Evaluation $eval */
foreach ($evals as $eval) {
$evalres = $eval->calc_score($stud_id);
$evalres = $eval->calc_score($stud_id, $type);
if ($type == 'ranking') {
var_dump($evalres);
}
$students[$stud_id] = $evalres[0];
if (isset($evalres) && $eval->get_weight() != 0) {
$evalweight = $eval->get_weight();
$weightsum += $evalweight;
$rescount++;
$ressum += (($evalres[0]/$evalres[1]) * $evalweight);
$ressum += $evalres[0] / $evalres[1] * $evalweight;
} else {
if ($eval->get_weight() != 0) {
$evalweight = $eval->get_weight();
@ -813,15 +894,20 @@ class Category implements GradebookItem
}
if (!empty($links)) {
$bestResult = 0;
$weight = 0;
/** @var EvalLink|ExerciseLink $link */
foreach ($links as $link) {
$linkres = $link->calc_score($stud_id);
foreach ($links as $link) {
$linkres = $link->calc_score($stud_id, $type);
if (!empty($linkres) && $link->get_weight() != 0) {
$students[$stud_id] = $linkres[0];
$linkweight = $link->get_weight();
$link_res_denom = $linkres[1] == 0 ? 1 : $linkres[1];
$rescount++;
$weightsum += $linkweight;
$ressum += ($linkres[0] / $link_res_denom) * $linkweight;
$ressum += $linkres[0] / $link_res_denom * $linkweight;
} else {
// Adding if result does not exists
if ($link->get_weight() != 0) {
@ -835,7 +921,22 @@ class Category implements GradebookItem
if ($rescount == 0) {
return null;
} else {
return array($ressum, $weightsum);
switch ($type) {
case 'best':
return array($ressum, $weightsum);
break;
case 'average':
return array($ressum, $weightsum);
break;
case 'ranking':
//var_dump($students);
return null;
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($ressum, $weightsum);
break;
}
}
}
@ -872,7 +973,7 @@ class Category implements GradebookItem
* @param string Course code
* @param int Session id
*/
public function get_root_categories_for_student ($stud_id, $course_code = null, $session_id = null)
public function get_root_categories_for_student($stud_id, $course_code = null, $session_id = null)
{
$main_course_user_table = Database :: get_main_table(TABLE_MAIN_COURSE_USER);
$tbl_grade_categories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
@ -1063,7 +1164,7 @@ class Category implements GradebookItem
*/
private function can_be_moved_to_cat ($cat)
{
return ($cat->get_id() != $this->get_id());
return $cat->get_id() != $this->get_id();
}
/**
@ -1073,7 +1174,7 @@ class Category implements GradebookItem
* of all underlying categories and evaluations. All links will
* be deleted as well !
*/
public function move_to_cat ($cat)
public function move_to_cat($cat)
{
$this->set_parent_id($cat->get_id());
if ($this->get_course_code() != $cat->get_course_code()) {
@ -1086,7 +1187,7 @@ class Category implements GradebookItem
/**
* Internal function used by move_to_cat()
*/
private function apply_course_code_to_children ()
private function apply_course_code_to_children()
{
$cats = Category::load(null, null, null, $this->id, null);
$evals = Evaluation::load(null, null, null, $this->id, null);
@ -1305,11 +1406,12 @@ class Category implements GradebookItem
/**
* Get appropriate subcategories visible for the user (and optionally the course and session)
* @param int $stud_id student id (default: all students)
* @param string Course code (optional)
* @param int Session ID (optional)
*
* @return array Array of subcategories
* @param int $stud_id student id (default: all students)
* @param string $course_code Course code (optional)
* @param int $session_id Session ID (optional)
* @param bool $order
* @return array Array of subcategories
*/
public function get_subcategories($stud_id = null, $course_code = null, $session_id = null, $order = null)
{
@ -1374,8 +1476,11 @@ class Category implements GradebookItem
*
* @return array
*/
public function get_evaluations($stud_id = null, $recursive = false, $course_code = '')
{
public function get_evaluations(
$stud_id = null,
$recursive = false,
$course_code = ''
) {
$evals = array();
if (empty($course_code)) {
@ -1384,14 +1489,14 @@ class Category implements GradebookItem
// 1 student
if (isset($stud_id) && !empty($stud_id)) {
// special case: this is the root
// Special case: this is the root
if ($this->id == 0) {
$evals = Evaluation::get_evaluations_with_result_for_student(0, $stud_id);
} else {
$evals = Evaluation::load(null,null, $course_code, $this->id, api_is_allowed_to_edit() ? null : 1);
}
} else {
// all students
// All students
// course admin
if ((api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) && !api_is_platform_admin()) {
// root
@ -1404,8 +1509,7 @@ class Category implements GradebookItem
// course independent
$evals = Evaluation::load(null, api_get_user_id(), null, $this->id, null);
}
} elseif (api_is_platform_admin()) {
//platform admin
} else {
$evals = Evaluation::load(null, null, $course_code, $this->id, null);
}
}
@ -1433,8 +1537,12 @@ class Category implements GradebookItem
*
* @return array
*/
public function get_links($stud_id = null, $recursive = false, $course_code = '', $sessionId = null)
{
public function get_links(
$stud_id = null,
$recursive = false,
$course_code = '',
$sessionId = null
) {
$links = array();
if (empty($course_code)) {
@ -1458,8 +1566,9 @@ class Category implements GradebookItem
$this->id,
api_is_allowed_to_edit() ? null : 1
);
} elseif (api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) {
// all students -> only for course/platform admin
//} elseif (api_is_allowed_to_edit() || api_is_drh() || api_is_session_admin()) {
} else {
// All students -> only for course/platform admin
$links = LinkFactory::load(
null,
null,
@ -1502,7 +1611,8 @@ class Category implements GradebookItem
public function getCategories($catId)
{
$tblGradeCategories = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql='SELECT * FROM '.$tblGradeCategories.' WHERE parent_id = '.intval($catId);
$sql = 'SELECT * FROM '.$tblGradeCategories.'
WHERE parent_id = '.intval($catId);
$result = Database::query($sql);
$allcats = Category::create_category_objects_from_sql_result($result);
@ -1561,7 +1671,8 @@ class Category implements GradebookItem
}
/**
* This function, locks a category , only one who can unlock it is the platform administrator.
* This function, locks a category , only one who can unlock it is
* the platform administrator.
* @param int locked 1 or unlocked 0
* @return bool
@ -1569,7 +1680,8 @@ class Category implements GradebookItem
public function lock($locked)
{
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
$sql = "UPDATE $table SET locked = '".intval($locked)."' WHERE id='".intval($this->id)."'";
$sql = "UPDATE $table SET locked = '".intval($locked)."'
WHERE id='".intval($this->id)."'";
Database::query($sql);
}
@ -1673,7 +1785,8 @@ class Category implements GradebookItem
$cattotal = Category::load($category_id);
$scoretotal = $cattotal[0]->calc_score($user_id);
//Do not remove this the gradebook/lib/fe/gradebooktable.class.php file load this variable as a global
// Do not remove this the gradebook/lib/fe/gradebooktable.class.php
// file load this variable as a global
$scoredisplay = ScoreDisplay::instance();
$my_score_in_gradebook = $scoredisplay->display_score($scoretotal, SCORE_SIMPLE);

@ -268,7 +268,12 @@ class Evaluation implements GradebookItem
*/
public function add()
{
if (isset($this->name) && isset($this->user_id) && isset($this->weight) && isset ($this->eval_max) && isset($this->visible)) {
if (isset($this->name) &&
isset($this->user_id) &&
isset($this->weight) &&
isset ($this->eval_max) &&
isset($this->visible)
) {
$tbl_grade_evaluations = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_EVALUATION);
$sql = 'INSERT INTO '.$tbl_grade_evaluations
@ -424,14 +429,15 @@ class Evaluation implements GradebookItem
}
$result = Database::query($sql);
$number=Database::fetch_row($result);
return ($number[0] != 0);
return $number[0] != 0;
}
/**
* Are there any results for this evaluation yet ?
* The 'max' property should not be changed then.
*/
public function has_results() {
public function has_results()
{
$tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
$sql='SELECT count(id) AS number FROM '.$tbl_grade_results
.' WHERE evaluation_id = '.intval($this->id);
@ -444,7 +450,8 @@ class Evaluation implements GradebookItem
/**
* Delete all results for this evaluation
*/
public function delete_results() {
public function delete_results()
{
$tbl_grade_results = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_RESULT);
$sql = 'DELETE FROM '.$tbl_grade_results.' WHERE evaluation_id = '.intval($this->id);
Database::query($sql);
@ -453,7 +460,8 @@ class Evaluation implements GradebookItem
/**
* Delete this evaluation and all underlying results.
*/
public function delete_with_results(){
public function delete_with_results()
{
$this->delete_results();
$this->delete();
}
@ -461,7 +469,8 @@ class Evaluation implements GradebookItem
/**
* Check if the given score is possible for this evaluation
*/
public function is_valid_score ($score) {
public function is_valid_score ($score)
{
return (is_numeric($score) && $score >= 0 && $score <= $this->eval_max);
}
@ -481,9 +490,11 @@ class Evaluation implements GradebookItem
$weight = 0;
$sumResult = 0;
$students = [];
/** @var Result $res */
foreach ($results as $res) {
$score = $res->get_score();
if ((!empty ($score)) || ($score == '0')) {
if (!empty($score) || $score == '0') {
$rescount++;
$sum += $score / $this->get_max();
$sumResult += $score;
@ -492,6 +503,7 @@ class Evaluation implements GradebookItem
}
$weight = $this->get_max();
}
$students[$res->get_user_id()] = $score;
}
if ($rescount == 0) {
@ -499,13 +511,20 @@ class Evaluation implements GradebookItem
} else if (isset($stud_id)) {
return array($score, $this->get_max());
} else {
if ($type == 'best') {
return array($bestResult, $weight);
}
if ($type == 'average') {
return array($sumResult/$rescount, $weight);
switch ($type) {
case 'best':
return array($bestResult, $weight);
break;
case 'average':
return array($sumResult/$rescount, $weight);
break;
case 'ranking':
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($sum, $rescount);
break;
}
return array($sum, $rescount);
}
}

@ -194,13 +194,14 @@ class ExerciseLink extends AbstractLink
in exercice/exercice.php, look for note-query-exe-results marker*/
$session_id = api_get_session_id();
$courseId = $this->getCourseId();
if (!$this->is_hp) {
$sql = "SELECT * FROM $tblStats
WHERE
exe_exo_id = ".intval($this->get_ref_id())." AND
orig_lp_id = 0 AND
exe_exo_id = ".intval($this->get_ref_id())." AND
orig_lp_id = 0 AND
orig_lp_item_id = 0 AND
status <> 'incomplete' AND
status <> 'incomplete' AND
session_id = $session_id";
if (isset($stud_id)) {
@ -210,7 +211,7 @@ class ExerciseLink extends AbstractLink
} else {
$sql = "SELECT * FROM $tblHp hp, $tblDoc doc
WHERE
WHERE
hp.c_id = $courseId AND
hp.exe_user_id = $stud_id AND
hp.exe_name = doc.path AND
@ -237,10 +238,11 @@ class ExerciseLink extends AbstractLink
$bestResult = 0;
$weight = 0;
$sumResult = 0;
while ($data = Database::fetch_array($scores, 'ASSOC')) {
if (!in_array($data['exe_user_id'], $students)) {
if (!isset($students[$data['exe_user_id']])) {
if ($data['exe_weighting'] != 0) {
$students[] = $data['exe_user_id'];
$students[$data['exe_user_id']] = $data['exe_result'];
$student_count++;
if ($data['exe_result'] > $bestResult) {
$bestResult = $data['exe_result'];
@ -251,16 +253,24 @@ class ExerciseLink extends AbstractLink
}
}
}
if ($student_count == 0) {
return null;
} else {
if ($type == 'best') {
return array($bestResult, $weight);
}
if ($type == 'average') {
return array($sumResult/$student_count, $weight);
switch ($type) {
case 'best':
return array($bestResult, $weight);
break;
case 'average':
return array($sumResult/$student_count, $weight);
break;
case 'ranking':
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($sum, $student_count);
break;
}
return array($sum, $student_count);
}
}
}

@ -1,5 +1,6 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Gradebook link to student publication item
* @author Bert Steppé
@ -51,12 +52,14 @@ class ForumThreadLink extends AbstractLink
$result = Database::query($sql);
$cats=array();
$cats = array();
while ($data=Database::fetch_array($result)) {
if ( isset($data['thread_title_qualify']) and $data['thread_title_qualify']!=""){
$cats[] = array ($data['thread_id'], $data['thread_title_qualify']);
if (isset($data['thread_title_qualify']) and
$data['thread_title_qualify'] != ""
) {
$cats[] = array($data['thread_id'], $data['thread_title_qualify']);
} else {
$cats[] = array ($data['thread_id'], $data['thread_title']);
$cats[] = array($data['thread_id'], $data['thread_title']);
}
}
return $cats;
@ -71,6 +74,7 @@ class ForumThreadLink extends AbstractLink
if (empty($this->course_code)) {
die('Error in get_not_created_links() : course code not set');
}
$tbl_grade_links = Database :: get_course_table(TABLE_FORUM_THREAD);
$tbl_item_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
$session_id = api_get_session_id();
@ -98,12 +102,11 @@ class ForumThreadLink extends AbstractLink
$cats[] = array ($data['thread_id'], $data['thread_title']);
}
}
$my_cats=isset($cats)?$cats:null;
$my_cats = isset($cats) ? $cats : null;
return $my_cats;
}
/**
* Has anyone done this exercise yet ?
*/
@ -162,7 +165,7 @@ class ForumThreadLink extends AbstractLink
$sumResult = 0;
while ($data = Database::fetch_array($scores)) {
if (!(array_key_exists($data['user_id'],$students))) {
if (!(array_key_exists($data['user_id'], $students))) {
if ($assignment['thread_qualify_max'] != 0) {
$students[$data['user_id']] = $data['qualify'];
$rescount++;
@ -179,13 +182,20 @@ class ForumThreadLink extends AbstractLink
if ($rescount == 0) {
return null;
} else {
if ($type == 'average') {
return array($sumResult/$rescount, $weight);
}
if ($type == 'best') {
return array($bestResult, $weight);
switch ($type) {
case 'best':
return array($bestResult, $weight);
break;
case 'average':
return array($sumResult/$rescount, $weight);
break;
case 'ranking':
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($sum, $rescount);
break;
}
return array($sum , $rescount);
}
}
}

@ -150,13 +150,21 @@ class LearnpathLink extends AbstractLink
if ($rescount == 0) {
return null;
} else {
if ($type == 'average') {
return array($sumResult/$rescount, 100);
}
if ($type == 'best') {
return array($bestResult, 100);
switch ($type) {
case 'best':
return array($bestResult, 100);
break;
case 'average':
return array($sumResult/$rescount, 100);
break;
case 'ranking':
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($sum, $rescount);
break;
}
return array($sum, $rescount);
}
}
}

@ -69,8 +69,6 @@ class Result
$this->score = $score;
}
// CRUD FUNCTIONS
/**
* Retrieve results and return them as an array of Result objects
* @param $id result id
@ -87,7 +85,8 @@ class Result
if (is_null($id) && is_null($user_id) && !is_null($evaluation_id)) {
// Verified_if_exist_evaluation
$sql = 'SELECT COUNT(*) AS count FROM ' . $tbl_grade_results . '
$sql = 'SELECT COUNT(*) AS count
FROM ' . $tbl_grade_results . '
WHERE evaluation_id="' . Database::escape_string($evaluation_id) . '";';
$result = Database::query($sql);
$existEvaluation = Database::result($result, 0, 0);

@ -219,6 +219,7 @@ class StudentPublicationLink extends AbstractLink
$bestResult = 0;
$weight = 0;
$sumResult = 0;
$myResult = 0;
while ($data = Database::fetch_array($scores)) {
if (!(array_key_exists($data['user_id'], $students))) {
@ -239,13 +240,20 @@ class StudentPublicationLink extends AbstractLink
if ($rescount == 0) {
return null;
} else {
if ($type == 'best') {
return array($bestResult, $weight);
switch ($type) {
case 'best':
return array($bestResult, $weight);
break;
case 'average':
return array($sumResult/$rescount, $weight);
break;
case 'ranking':
return AbstractLink::getCurrentUserRanking($students);
break;
default:
return array($sum, $rescount);
break;
}
if ($type == 'average') {
return array($sumResult/$rescount, $weight);
}
return array($sum, $rescount);
}
}
}

@ -10,6 +10,9 @@ class SurveyLink extends AbstractLink
{
private $survey_table = null;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
@ -95,9 +98,14 @@ class SurveyLink extends AbstractLink
$sql = 'SELECT survey_id, title, code
FROM '.$this->get_survey_table().' AS srv
WHERE survey_id NOT IN
(SELECT ref_id FROM '.$tbl_grade_links.'
WHERE type = '.LINK_SURVEY." AND course_code = '".$this->get_course_code()."'"
.') AND srv.session_id='.api_get_session_id().'';
(
SELECT ref_id FROM '.$tbl_grade_links.'
WHERE
type = '.LINK_SURVEY.' AND
course_code = '".$this->get_course_code()."'
)
AND srv.session_id = '.api_get_session_id();
$result = Database::query($sql);
$links = array();
@ -172,7 +180,7 @@ class SurveyLink extends AbstractLink
if ($get_individual_score) {
// for 1 student
if ($data = Database::fetch_array($sql_result)) {
return array ($data['answered'] ? $max_score : 0, $max_score);
return array($data['answered'] ? $max_score : 0, $max_score);
}
return array(0, $max_score);
} else {
@ -194,13 +202,21 @@ class SurveyLink extends AbstractLink
if ($rescount == 0) {
return null;
}
if ($type == 'best') {
return array($bestResult, $rescount);
}
if ($type == 'average') {
return array($sum, $rescount);
switch ($type) {
case 'best':
return array($bestResult, $rescount);
break;
case 'average':
return array($sum, $rescount);
break;
case 'ranking':
return null;
break;
default:
return array($sum, $rescount);
break;
}
return array($sum, $rescount);
}
}

@ -54,7 +54,7 @@ class GradebookTable extends SortableTable
} else {
$this->set_header($column++, get_lang('Weight'), false);
$this->set_header($column++, get_lang('Result'), false);
$this->set_header($column++, get_lang('Global'), false);
$this->set_header($column++, get_lang('Ranking'), false);
$this->set_header($column++, get_lang('Best'), false);
$this->set_header($column++, get_lang('Average'), false);
@ -114,7 +114,7 @@ class GradebookTable extends SortableTable
//variables load in index.php
global $certificate_min_score;
// determine sorting type
$col_adjust = (api_is_allowed_to_edit() ? 1 : 0);
$col_adjust = api_is_allowed_to_edit() ? 1 : 0;
// By id
$this->column = 5;
@ -150,10 +150,27 @@ class GradebookTable extends SortableTable
$course_code = api_get_course_id();
$session_id = api_get_session_id();
$status_user = api_get_status_of_user_in_course($user_id, $course_code);
if (empty($session_id)) {
$statusToFilter = STUDENT;
} else {
$statusToFilter = 0;
}
$studentList = CourseManager::get_user_list_from_course_code(
$course_code,
$session_id,
null,
null,
$statusToFilter
);
$data_array = $this->datagen->get_data(
$sorting,
$from,
$this->per_page
$this->per_page,
false,
$studentList
);
// generate the data to display
@ -164,17 +181,22 @@ class GradebookTable extends SortableTable
$total_categories_weight = 0;
$scoredisplay = ScoreDisplay :: instance();
$totalResult = [0, 0];
$totalGlobal = [0, 0];
$totalBest = [0, 0];
$totalAverage = [0, 0];
// Categories.
foreach ($data_array as $data) {
// list of items inside the gradebook (exercises, lps, forums, etc)
$row = array();
/** @var AbstractLink $item */
$item = $item_category = $data[0];
$item = $mainCategory = $data[0];
//if the item is invisible, wrap it in a span with class invisible
$invisibility_span_open = (api_is_allowed_to_edit() && $item->is_visible() == '0') ? '<span class="invisible">' : '';
$invisibility_span_close = (api_is_allowed_to_edit() && $item->is_visible() == '0') ? '</span>' : '';
$invisibility_span_open = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '<span class="invisible">' : '';
$invisibility_span_close = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '</span>' : '';
// Id
if (api_is_allowed_to_edit(null, true)) {
@ -223,7 +245,7 @@ class GradebookTable extends SortableTable
if (api_is_allowed_to_edit(null, true)) {
$weight_total_links += $data[3];
} else {
$cattotal = Category :: load($_GET['selectcat']);
$cattotal = Category::load($_GET['selectcat']);
$scoretotal = $cattotal[0]->calc_score(api_get_user_id());
$item_value = $scoredisplay->display_score($scoretotal, SCORE_SIMPLE);
}
@ -239,13 +261,18 @@ class GradebookTable extends SortableTable
$score = $item->calc_score(api_get_user_id());
if (!empty($score[1])) {
$categoryScoreArray = $score;
$completeScore = $scoredisplay->display_score($score, SCORE_DIV_PERCENT);
$score = $score[0]/$score[1]*$item->get_weight();
$score = $scoredisplay->display_score(array($score, null), SCORE_SIMPLE);
$categoryScore = $scoredisplay->display_score(array($score, $mainCategoryWeight), SCORE_DIV);
$categoryScore = $scoredisplay->display_score(
array($score, $mainCategoryWeight),
SCORE_DIV
);
$scoreToDisplay = Display::tip($score, $completeScore);
} else {
$categoryScoreArray = [0, $item->get_weight()];
$scoreToDisplay = '-';
$categoryScore = null;
}
@ -255,22 +282,35 @@ class GradebookTable extends SortableTable
$value_data = isset($data[4]) ? $data[4] : null;
$best = isset($data['best']) ? $data['best'] : null;
$average = isset($data['average']) ? $data['average'] : null;
//if (!is_null($value_data)) {
// Student result
$row[] = Display::tag('h4', $value_data);
// Global
$row[] = Display::tag('h4', $categoryScore);
// Best
$row[] = Display::tag('h4', $best);
// Average
$row[] = Display::tag('h4', $average);
$ranking = isset($data['ranking']) ? $data['ranking'] : null;
$totalResult = [
$totalResult[0] + $data['result_score'][0],
$totalResult[1] + $data['result_score'][1],
];
$totalBest = [
$totalBest[0] + $data['best_score'][0],
$totalBest[1] + $data['best_score'][1],
];
$totalAverage = [
$totalAverage[0] + $data['average_score'][0],
$totalAverage[1] + $data['average_score'][1],
];
// Student result
$row[] = $value_data;
// Ranking
$row[] = $ranking;
// Best
$row[] = $best;
// Average
$row[] = $average;
if (get_class($item) == 'Category') {
$row[] = $this->build_edit_column($item);
/*} else {
}*/
}
} else {
$row[] = $scoreToDisplay;
@ -300,20 +340,20 @@ class GradebookTable extends SortableTable
$data_array = $sub_cat_info->get_data($sorting, $from, $this->per_page);
$total_weight = 0;
//$score = $cats[0]->calc_score(api_get_user_id());
//$categoryScore = $scoredisplay->display_score(array($score, $cats[0]->get_weight()), SCORE_DIV);
// Links.
foreach ($data_array as $data) {
$row = array();
$item = $data[0];
//if the item is invisible, wrap it in a span with class invisible
$invisibility_span_open = (api_is_allowed_to_edit() && $item->is_visible() == '0') ? '<span class="invisible">' : '';
$invisibility_span_close = (api_is_allowed_to_edit() && $item->is_visible() == '0') ? '</span>' : '';
$invisibility_span_open = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '<span class="invisible">' : '';
$invisibility_span_close = api_is_allowed_to_edit() && $item->is_visible() == '0' ? '</span>' : '';
$main_categories[$parent_id]['children'][$item->get_id()]['name'] = $item->get_name();
$main_categories[$parent_id]['children'][$item->get_id()]['weight'] = $item->get_weight();
if (isset($item)) {
$main_categories[$parent_id]['children'][$item->get_id()]['name'] = $item->get_name();
$main_categories[$parent_id]['children'][$item->get_id()]['weight'] = $item->get_weight();
}
if (api_is_allowed_to_edit(null, true)) {
$row[] = $this->build_id_column($item);
@ -348,33 +388,33 @@ class GradebookTable extends SortableTable
$row[] = $this->build_edit_column($item);
}
} else {
//students get the results and certificates columns
// Students get the results and certificates columns
$eval_n_links = array_merge($alleval, $alllink);
if (count($eval_n_links)> 0 && $status_user!=1 ) {
if (count($eval_n_links)> 0 && $status_user != 1) {
$value_data = isset($data[4]) ? $data[4] : null;
if (!is_null($value_data)) {
$score = $item->calc_score(api_get_user_id());
$new_score = $data[3] * $score[0] / $score[1];
$new_score = floatval(number_format($new_score, api_get_setting('gradebook_number_decimals')));
//$row[] = Display::tip($new_score, $data[4]);
//$score = $item->calc_score(api_get_user_id());
//$new_score = $data[3] * $score[0] / $score[1];
//$new_score = floatval(number_format($new_score, api_get_setting('gradebook_number_decimals')));
// Result
$row[] = $value_data;
$best = isset($data['best']) ? $data['best'] : null;
$average = isset($data['average']) ? $data['average'] : null;
$ranking = isset($data['ranking']) ? $data['ranking'] : null;
// Global
$categoryScore = $scoredisplay->display_score(
array($new_score, $cattotal[0]->get_weight()),
SCORE_DIV
);
$row[] = Display::tag('h4', $categoryScore);
// Ranking
$row[] = $ranking;
// Best
$row[] = Display::tag('h4', $best);
$row[] = $best;
// Average
$row[] = Display::tag('h4', $average);
$row[] = $average;
}
}
if (!empty($cats)) {
$row[] = null;
}
@ -389,7 +429,12 @@ class GradebookTable extends SortableTable
// Compare the category weight to the sum of all weights inside the category
if (intval($total_weight) == $category_weight) {
$label = null;
$total = GradebookUtils::score_badges(array($total_weight.' / '.$category_weight, '100'));
$total = GradebookUtils::score_badges(
array(
$total_weight.' / '.$category_weight,
'100'
)
);
} else {
$label = Display::return_icon(
'warning.png',
@ -413,24 +458,85 @@ class GradebookTable extends SortableTable
} //end looping categories
if (api_is_allowed_to_edit()) {
// Total for teacher.
if (count($main_cat) > 1) {
$main_weight = intval($main_cat[0]->get_weight());
if (intval($total_categories_weight) == $main_weight) {
$total = GradebookUtils::score_badges(array($total_categories_weight.' / '.$main_weight, '100'));
$total = GradebookUtils::score_badges(
array($total_categories_weight.' / '.$main_weight, '100')
);
} else {
$total = Display::badge($total_categories_weight.' / '.$main_weight, 'warning');
}
$row = array(null, null, '<h3>'.get_lang('Total').'</h3>', null, $total);
$row = array(
null,
null,
'<h3>' . get_lang('Total') . '</h3>',
null,
$total
);
$sortable_data[] = $row;
}
} else {
// Total for student.
if (count($main_cat) > 1) {
$main_weight = intval($main_cat[0]->get_weight());
$global = null;
$average = null;
$totalResult = $scoredisplay->display_score(
$totalResult,
SCORE_DIV
);
$totalRanking = array();
foreach ($studentList as $student) {
$score = $main_cat[0]->calc_score($student['user_id']);
$totalRanking[$student['user_id']] = $score[0];
}
$totalRanking = AbstractLink::getCurrentUserRanking($totalRanking);
$totalRanking = $scoredisplay->display_score(
$totalRanking,
SCORE_DIV
);
$totalBest = $scoredisplay->display_score(
$totalBest,
SCORE_DIV
);
$totalAverage = $scoredisplay->display_score(
$totalAverage,
SCORE_DIV
);
$row = array(
null,
'<h3>' . get_lang('Total') . '</h3>',
null,
$main_weight,
$totalResult,
$totalRanking,
$totalBest,
$totalAverage,
);
$sortable_data[] = $row;
}
}
// warning messages
// Warning messages
$view = isset($_GET['view']) ? $_GET['view']: null;
if (api_is_allowed_to_edit()) {
if (isset($_GET['selectcat']) && $_GET['selectcat'] > 0 && $view <> 'presence') {
if (api_is_allowed_to_edit()) {
if (isset($_GET['selectcat']) &&
$_GET['selectcat'] > 0 &&
$view <> 'presence'
) {
$id_cat = intval($_GET['selectcat']);
$category = Category::load($id_cat);
@ -485,14 +591,19 @@ class GradebookTable extends SortableTable
}
}
if (is_array($weight_categories) && is_array($certificate_min_scores) && is_array($course_codes)) {
if (is_array($weight_categories) &&
is_array($certificate_min_scores) &&
is_array($course_codes)
) {
$warning_message = '';
for ($x = 0; $x<count($weight_categories);$x++) {
$weight_category = intval($weight_categories[$x]);
$certificate_min_score = intval($certificate_min_scores[$x]);
$course_code = $course_codes[$x];
if (empty($certificate_min_score) || ($certificate_min_score > $weight_category)) {
if (empty($certificate_min_score) ||
($certificate_min_score > $weight_category)
) {
$warning_message .= $course_code .'&nbsp;-&nbsp;'.get_lang('CertificateMinimunScoreIsRequiredAndMustNotBeMoreThan').'&nbsp;'.$weight_category.'<br />';
}
}
@ -511,7 +622,7 @@ class GradebookTable extends SortableTable
* @param $item
* @return mixed
*/
private function build_certificate_min_score ($item)
private function build_certificate_min_score($item)
{
return $item->get_certificate_min_score();
}
@ -529,7 +640,7 @@ class GradebookTable extends SortableTable
* @param $item
* @return mixed
*/
private function build_course_code ($item)
private function build_course_code($item)
{
return $item->get_course_code();
}
@ -538,7 +649,7 @@ class GradebookTable extends SortableTable
* @param $item
* @return string
*/
private function build_id_column ($item)
private function build_id_column($item)
{
switch ($item->get_item_type()) {
// category
@ -558,7 +669,7 @@ class GradebookTable extends SortableTable
* @param array $attributes
* @return string
*/
private function build_type_column ($item, $attributes = array())
private function build_type_column($item, $attributes = array())
{
return GradebookUtils::build_type_icon_tag($item->get_icon_name(), $attributes);
}
@ -592,11 +703,9 @@ class GradebookTable extends SortableTable
case 'E' :
$cat = new Category();
$course_id = CourseManager::get_course_by_category($_GET['selectcat']);
$show_message = $cat->show_message_resource_delete($course_id);
// course/platform admin can go to the view_results page
if (api_is_allowed_to_edit() && $show_message===false) {
if ($item->get_type() == 'presence') {
return '&nbsp;'
@ -616,24 +725,23 @@ class GradebookTable extends SortableTable
. $item->get_name()
. '</a>';
} elseif ($show_message===false && !api_is_allowed_to_edit() && !(ScoreDisplay :: instance()->is_custom())) {
} elseif ($show_message === false && !api_is_allowed_to_edit() && !ScoreDisplay :: instance()->is_custom()) {
return '&nbsp;'
. '<a href="gradebook_statistics.php?selecteval=' . $item->get_id() . '">'
. $item->get_name()
. '</a>';
} else {
return '['.get_lang('Evaluation').']&nbsp;&nbsp;'.$item->get_name().$show_message;
}
// link
case 'L' :
$cat = new Category();
$course_id = CourseManager::get_course_by_category($_GET['selectcat']);
$show_message = $cat->show_message_resource_delete($course_id);
case 'L':
// link
$cat = new Category();
$course_id = CourseManager::get_course_by_category($_GET['selectcat']);
$show_message = $cat->show_message_resource_delete($course_id);
$url = $item->get_link();
if (isset($url) && $show_message===false) {
if (isset($url) && $show_message === false) {
$text = '&nbsp;<a href="' . $item->get_link() . '">'
. $item->get_name()
. '</a>';

@ -553,12 +553,12 @@ class FlatViewDataGenerator
$score = $item->calc_score($user_id);
$real_score = $score;
$divide = (($score[1])==0 ) ? 1 : $score[1];
$divide = isset($score[1]) && !empty($score[1]) ? $score[1] : 1;
// Sub cat weight
$sub_cat_percentage = $sum_categories_weight_array[$item->get_category_id()];
$item_value = $score[0]/$divide;
$item_value = isset($score[0]) ? $score[0]/$divide : 0;
// Fixing total when using one or multiple gradebooks.
if (empty($parentCategoryIdFilter)) {

@ -80,7 +80,7 @@ class GradebookDataGenerator
* 4: date
* 5: student's score (if student logged in)
*/
public function get_data($sorting = 0, $start = 0, $count = null, $ignore_score_color = false)
public function get_data($sorting = 0, $start = 0, $count = null, $ignore_score_color = false, $studentList = array())
{
//$status = CourseManager::get_user_in_course_status(api_get_user_id(), api_get_course_id());
// do some checks on count, redefine if invalid value
@ -112,39 +112,111 @@ class GradebookDataGenerator
// get selected items
$visibleitems = array_slice($allitems, $start, $count);
//status de user in course
$user_id = api_get_user_id();
$userId = api_get_user_id();
$course_code = api_get_course_id();
$status_user = api_get_status_of_user_in_course($user_id, $course_code);
$sessionId = api_get_session_id();
$status_user = api_get_status_of_user_in_course($userId, $course_code);
if (empty($sessionId)) {
$statusToFilter = STUDENT;
} else {
$statusToFilter = 0;
}
$userCount = CourseManager::get_user_list_from_course_code(
$course_code,
$sessionId,
null,
null,
$statusToFilter,
true
);
// Generate the data to display
$data = array();
/** @var GradebookItem $item */
$totalWeight = 0;
foreach ($visibleitems as $item) {
$row = array ();
$row = array();
$row[] = $item;
$row[] = $item->get_name();
// display the 2 first line of description, and all description on mouseover (https://support.chamilo.org/issues/6588)
$row[] = '<span title="'.api_remove_tags_with_space($item->get_description()).'">'.
api_get_short_text_from_html($item->get_description(), 160).'</span>';
$totalWeight += $item->get_weight();
$row[] = $item->get_weight();
if (count($this->evals_links) > 0) {
// Items inside a category.
if (!api_is_allowed_to_edit() || $status_user != 1 ) {
$row[] = $this->build_result_column($item, $ignore_score_color);
$row['best'] = $this->buildBestResultColumn($item);
$row['average'] = $this->buildAverageResultColumn($item);
$resultColumn = $this->build_result_column(
api_get_user_id(),
$item,
$ignore_score_color
);
$row[] = $resultColumn['display'];
$row['result_score'] = $resultColumn['score'];
// Best
$best = $this->buildBestResultColumn($item);
$row['best'] = $best['display'];
$row['best_score'] = $best['score'];
// Average
$average = $this->buildAverageResultColumn($item);
$row['average'] = $average['display'];
$row['average_score'] = $average['score'];
// Ranking
$ranking = $this->buildRankingColumn($item, $userCount);
$row['ranking'] = $ranking['display'];
$row['ranking_score'] = $ranking['score'];
$row[] = $item;
}
} else {
$row[] = $this->build_result_column($item, $ignore_score_color, true);
$row['best'] = $this->buildBestResultColumn($item);
$row['average'] = $this->buildAverageResultColumn($item);
// Category.
// Result
$result = $this->build_result_column($userId, $item, $ignore_score_color, true);
$row[] = $result['display'];
$row['result_score'] = $result['score'];
// Best
$best = $this->buildBestResultColumn($item);
$row['best'] = $best['display'];
$row['best_score'] = $best['score'];
// Average
$average = $this->buildAverageResultColumn($item);
$row['average'] = $average['display'];
$row['average_score'] = $average['score'];
// Ranking
$rankingStudentList = array();
foreach ($studentList as $user) {
$score = $this->build_result_column(
$user['user_id'],
$item,
$ignore_score_color,
true
);
$rankingStudentList[$user['user_id']] = $score['display'][0];
}
$scoreDisplay = ScoreDisplay::instance();
$score = AbstractLink::getCurrentUserRanking($rankingStudentList);
$row['ranking'] = $scoreDisplay->display_score($score, SCORE_DIV);
}
$data[] = $row;
}
return $data;
}
/**
* Get best result of an item
* @param GradebookItem $item
@ -161,7 +233,10 @@ class GradebookDataGenerator
$scoreDisplay = ScoreDisplay :: instance();
return $scoreDisplay->display_score($score, SCORE_DIV);
return array(
'display' => $scoreDisplay->display_score($score, SCORE_DIV),
'score' => $score
);
}
/**
@ -172,18 +247,43 @@ class GradebookDataGenerator
{
$score = $item->calc_score(null, 'average');
$scoreDisplay = ScoreDisplay :: instance();
return $scoreDisplay->display_score($score, SCORE_DIV);
return array(
'display' => $scoreDisplay->display_score($score, SCORE_DIV),
'score' => $score
);
}
/**
* @param GradebookItem $item
* @return string
*/
private function buildRankingColumn(GradebookItem $item, $userCount = 0)
{
$score = $item->calc_score(null, 'ranking');
$score[1] = $userCount;
$scoreDisplay = ScoreDisplay::instance();
return array(
'display' => $scoreDisplay->display_score($score, SCORE_DIV),
'score' => $score
);
}
/**
* @param int $userId
* @param GradebookItem $item
* @param $ignore_score_color
* @return null|string
*/
private function build_result_column($item, $ignore_score_color, $forceSimpleResult = false)
{
$scoredisplay = ScoreDisplay :: instance();
$score = $item->calc_score(api_get_user_id());
private function build_result_column(
$userId,
$item,
$ignore_score_color,
$forceSimpleResult = false
) {
$scoredisplay = ScoreDisplay::instance();
$score = $item->calc_score($userId);
if (!empty($score)) {
switch ($item->get_item_type()) {
@ -195,11 +295,24 @@ class GradebookDataGenerator
$displaytype |= SCORE_IGNORE_SPLIT;
}
if ($forceSimpleResult) {
return $scoredisplay->display_score($score, SCORE_DIV);
return
array(
'display' => $scoredisplay->display_score(
$score,
SCORE_DIV
),
'score' => $score
);
}
return get_lang('Total') . ' : '. $scoredisplay->display_score($score, $displaytype);
return array(
'display' => get_lang('Total') . ' : '. $scoredisplay->display_score($score, $displaytype),
'score' => $score
);
} else {
return '';
return array(
'display' => null,
'score' => $score
);
}
break;
// evaluation and link
@ -209,10 +322,17 @@ class GradebookDataGenerator
if ($ignore_score_color) {
$displaytype |= SCORE_IGNORE_SPLIT;
}*/
return $scoredisplay->display_score($score, SCORE_DIV_PERCENT_WITH_CUSTOM);
return array(
'display' => $scoredisplay->display_score($score, SCORE_DIV),
'score' => $score,
);
}
}
return null;
return array(
'display' => null,
'score' => null
);
}
/**

@ -3,7 +3,7 @@
/**
* Class ScoreDisplay
* Class to display scores according to the settings made by the platform admin.
* Display scores according to the settings made by the platform admin.
* This class works as a singleton: call instance() to retrieve an object.
* @author Bert Steppé
* @package chamilo.gradebook
@ -19,6 +19,7 @@ class ScoreDisplay
/**
* Get the instance of this class
* @param int $category_id
*/
public static function instance($category_id = 0)
{
@ -48,7 +49,6 @@ class ScoreDisplay
} else {
return (($score1[0]/$score1[1]) < ($score2[0]/$score2[1]) ? -1 : 1);
}
}
}
@ -224,6 +224,10 @@ class ScoreDisplay
Database::query($sql);
}
/**
* @param int $category_id
* @return bool
*/
public function insert_defaults($category_id)
{
if (empty($category_id)) {
@ -252,6 +256,9 @@ class ScoreDisplay
}
}
/**
* @return int|null|string
*/
public function get_number_decimals()
{
$number_decimals = api_get_setting('gradebook_number_decimals');
@ -284,8 +291,12 @@ class ScoreDisplay
*
* @return string
*/
public function display_score($score, $type = SCORE_DIV_PERCENT, $what = SCORE_BOTH, $no_color = false)
{
public function display_score(
$score,
$type = SCORE_DIV_PERCENT,
$what = SCORE_BOTH,
$no_color = false
) {
$my_score = $score == 0 ? 1 : $score;
if ($type == SCORE_BAR) {
@ -306,8 +317,9 @@ class ScoreDisplay
}
if ($this->coloring_enabled && $no_color == false) {
$my_score_denom = ($score[1]==0)?1:$score[1];
if (($score[0] / $my_score_denom) < ($this->color_split_value / 100)) {
$my_score_denom = isset($score[1]) && !empty($score[1]) ? $score[1] : 1;
$scoreCleaned = isset($score[0]) ? $score[0] : 0;
if (($scoreCleaned / $my_score_denom) < ($this->color_split_value / 100)) {
$display = Display::tag('font', $display, array('color'=>'red'));
}
}
@ -319,7 +331,7 @@ class ScoreDisplay
* @param $type
* @return float|string
*/
private function display_default ($score, $type)
private function display_default($score, $type)
{
switch ($type) {
case SCORE_DIV : // X / Y
@ -410,10 +422,10 @@ class ScoreDisplay
private function display_as_div($score)
{
if ($score == 1) {
return '0/0';
return '0 / 0';
} else {
$score[0] =$this->format_score($score[0]);
$score[1] =$this->format_score($score[1]);
$score[0] = isset($score[0]) ? $this->format_score($score[0]) : 0;
$score[1] = isset($score[1]) ? $this->format_score($score[1]) : 0;
return $score[0] . ' / ' . $score[1];
}
}
@ -422,7 +434,7 @@ class ScoreDisplay
* Depends on the teacher's configuration of thresholds. i.e. [0 50] "Bad", [50:100] "Good"
* @param array $score
*/
private function display_custom ($score)
private function display_custom($score)
{
$my_score_denom= ($score[1]==0) ? 1 : $score[1];
$scaledscore = $score[0] / $my_score_denom;
@ -480,7 +492,9 @@ class ScoreDisplay
} else {
$category_id = $this->get_current_gradebook_category_id();
}
$sql = 'SELECT * FROM '.$tbl_display.' WHERE category_id = '.$category_id.' ORDER BY score';
$sql = 'SELECT * FROM '.$tbl_display.'
WHERE category_id = '.$category_id.'
ORDER BY score';
$result = Database::query($sql);
return Database::store_result($result,'ASSOC');
}

@ -154,9 +154,11 @@ class UserDataGenerator
return $data;
}
// Sort functions
// Make sure to only use functions as defined in the GradebookItem interface !
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_type($item1, $item2)
{
if ($item1->get_item_type() == $item2->get_item_type()) {
@ -166,6 +168,11 @@ class UserDataGenerator
}
}
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_course($item1, $item2)
{
$name1 = api_strtolower($this->get_course_name_from_code_cached($item1->get_course_code()));
@ -173,6 +180,11 @@ class UserDataGenerator
return api_strnatcmp($name1, $name2);
}
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_category($item1, $item2)
{
$cat1 = $this->get_category_cached($item1->get_category_id());
@ -182,11 +194,21 @@ class UserDataGenerator
return api_strnatcmp($name1, $name2);
}
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_name($item1, $item2)
{
return api_strnatcmp($item1->get_name(),$item2->get_name());
}
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_average($item1, $item2)
{
$score1 = $this->avgcache[$item1->get_item_type() . $item1->get_id()];
@ -194,6 +216,11 @@ class UserDataGenerator
return $this->compare_scores($score1, $score2);
}
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_score($item1, $item2)
{
$score1 = $this->scorecache[$item1->get_item_type() . $item1->get_id()];
@ -201,6 +228,11 @@ class UserDataGenerator
return $this->compare_scores($score1, $score2);
}
/**
* @param $item1
* @param $item2
* @return int
*/
function sort_by_mask($item1, $item2)
{
$score1 = $this->scorecache[$item1->get_item_type() . $item1->get_id()];
@ -208,7 +240,12 @@ class UserDataGenerator
return ScoreDisplay :: compare_scores_by_custom_display($score1, $score2);
}
function compare_scores ($score1, $score2)
/**
* @param $score1
* @param $score2
* @return int
*/
function compare_scores($score1, $score2)
{
if (!isset($score1)) {
return (isset($score2) ? 1 : 0);
@ -221,19 +258,32 @@ class UserDataGenerator
}
}
private function build_course_name ($item)
/**
* @param $item
* @return mixed
*/
private function build_course_name($item)
{
return $this->get_course_name_from_code_cached($item->get_course_code());
}
private function build_category_name ($item)
/**
* @param $item
* @return string
*/
private function build_category_name($item)
{
$cat = $this->get_category_cached($item->get_category_id());
return $this->get_category_name_to_display($cat);
}
private function build_average_column ($item, $ignore_score_color)
/**
* @param $item
* @param $ignore_score_color
* @return string
*/
private function build_average_column($item, $ignore_score_color)
{
if (isset($this->avgcache)) {
$avgscore = $this->avgcache[$item->get_item_type() . $item->get_id()];
@ -249,7 +299,12 @@ class UserDataGenerator
return $scoredisplay->display_score($avgscore, $displaytype);
}
private function build_result_column ($item, $ignore_score_color)
/**
* @param $item
* @param $ignore_score_color
* @return string
*/
private function build_result_column($item, $ignore_score_color)
{
$studscore = $this->scorecache[$item->get_item_type() . $item->get_id()];
$scoredisplay = ScoreDisplay :: instance();
@ -260,6 +315,11 @@ class UserDataGenerator
return $scoredisplay->display_score($studscore, $displaytype, SCORE_ONLY_DEFAULT);
}
/**
* @param $item
* @param $ignore_score_color
* @return string
*/
private function build_mask_column($item, $ignore_score_color)
{
$studscore = $this->scorecache[$item->get_item_type() . $item->get_id()];
@ -271,8 +331,12 @@ class UserDataGenerator
return $scoredisplay->display_score($studscore, $displaytype, SCORE_ONLY_CUSTOM);
}
private function get_course_name_from_code_cached ($coursecode) {
/**
* @param $coursecode
* @return mixed
*/
private function get_course_name_from_code_cached($coursecode)
{
if (isset ($this->coursecodecache)
&& isset ($this->coursecodecache[$coursecode])) {
return $this->coursecodecache[$coursecode];
@ -283,7 +347,12 @@ class UserDataGenerator
}
}
private function get_category_cached ($category_id) {
/**
* @param $category_id
* @return null
*/
private function get_category_cached($category_id)
{
if (isset ($this->categorycache)
&& isset ($this->categorycache[$category_id])) {
return $this->categorycache[$category_id];
@ -297,7 +366,12 @@ class UserDataGenerator
}
}
private function get_category_name_to_display ($cat) {
/**
* @param $cat
* @return string
*/
private function get_category_name_to_display($cat)
{
if (isset($cat)) {
if ($cat->get_parent_id() == '0' || $cat->get_parent_id() == null){
return '';

@ -101,7 +101,7 @@ class Attendance
*/
public static function get_attendance_data($from, $number_of_items, $column, $direction)
{
$tbl_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
$tbl_attendance = Database::get_course_table(TABLE_ATTENDANCE);
$course_id = api_get_course_int_id();
$session_id = api_get_session_id();
$condition_session = api_get_session_condition($session_id);
@ -114,8 +114,10 @@ class Attendance
}
$active_plus = '';
if ((isset($_GET['isStudentView']) && $_GET['isStudentView'] == 'true') || !api_is_allowed_to_edit(null, true)) {
$active_plus = 'AND att.active = 1';
if ((isset($_GET['isStudentView']) && $_GET['isStudentView'] == 'true') ||
!api_is_allowed_to_edit(null, true)
) {
$active_plus = ' AND att.active = 1';
}
$sql = "SELECT
@ -127,7 +129,9 @@ class Attendance
att.active AS col5,
att.session_id
FROM $tbl_attendance att
WHERE c_id = $course_id $active_plus $condition_session
WHERE
att.active <> 2 AND
c_id = $course_id $active_plus $condition_session
ORDER BY col$column $direction
LIMIT $from,$number_of_items ";
@ -139,11 +143,13 @@ class Attendance
$param_gradebook = '&gradebook='.$_SESSION['gradebook'];
}
$user_info = api_get_user_info();
$allowDelete = api_get_configuration_value('allow_delete_attendance');
while ($attendance = Database::fetch_row($res)) {
$student_param = '';
if (api_is_drh() && $_GET['student_id']) {
$student_param = '&student_id='.Security::remove_XSS($_GET['student_id']);
$student_param = '&student_id='.intval($_GET['student_id']);
}
$session_star = '';
@ -182,21 +188,42 @@ class Attendance
$actions .= '<center>';
if (api_is_platform_admin()) {
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_edit&attendance_id='.$attendance[0].$param_gradebook.'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>&nbsp;';
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_edit&attendance_id='.$attendance[0].$param_gradebook.'">'.
Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>&nbsp;';
// Visible
if ($attendance[5] == 1) {
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_delete&attendance_id='.$attendance[0].$param_gradebook.'">'.Display::return_icon('visible.png', get_lang('Hide'), array(), ICON_SIZE_SMALL).'</a>';
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_set_invisible&attendance_id='.$attendance[0].$param_gradebook.'">'.
Display::return_icon('visible.png', get_lang('Hide'), array(), ICON_SIZE_SMALL).'</a>';
} else {
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_restore&attendance_id='.$attendance[0].$param_gradebook.'">'.Display::return_icon('invisible.png', get_lang('Show'), array(), ICON_SIZE_SMALL).'</a>';
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_set_visible&attendance_id='.$attendance[0].$param_gradebook.'">'.
Display::return_icon('invisible.png', get_lang('Show'), array(), ICON_SIZE_SMALL).'</a>';
$attendance[2] = '<span class="muted">'.$attendance[2].'</span>';
}
if ($allowDelete) {
$actions .= '<a href="index.php?' . api_get_cidreq() . '&action=attendance_delete&attendance_id=' . $attendance[0] . $param_gradebook . '">' .
Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
}
} else {
$is_locked_attendance = self::is_locked_attendance($attendance[0]);
if ($is_locked_attendance) {
$actions .= Display::return_icon('edit_na.png', get_lang('Edit')).'&nbsp;';
$actions .= Display::return_icon('visible.png', get_lang('Hide'));
} else {
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_edit&attendance_id='.$attendance[0].$param_gradebook.'">'.Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>&nbsp;';
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_delete&attendance_id='.$attendance[0].$param_gradebook.'">'.Display::return_icon('visible.png', get_lang('Hide'), array(), ICON_SIZE_SMALL).'</a>';
$actions .= '<a href="index.php?'.api_get_cidreq().'&action=attendance_edit&attendance_id='.$attendance[0].$param_gradebook.'">'.
Display::return_icon('edit.png', get_lang('Edit'), array(), ICON_SIZE_SMALL).'</a>&nbsp;';
if ($attendance[5] == 1) {
$actions .= ' <a href="index.php?'.api_get_cidreq().'&action=attendance_set_invisible&attendance_id='.$attendance[0].$param_gradebook.'">'.
Display::return_icon('visible.png', get_lang('Hide'), array(), ICON_SIZE_SMALL).'</a>';
} else {
$actions .= ' <a href="index.php?'.api_get_cidreq().'&action=attendance_set_visible&attendance_id='.$attendance[0].$param_gradebook.'">'.
Display::return_icon('invisible.png', get_lang('Show'), array(), ICON_SIZE_SMALL).'</a>';
$attendance[2] = '<span class="muted">'.$attendance[2].'</span>';
}
if ($allowDelete) {
$actions .= ' <a href="index.php?' . api_get_cidreq() . '&action=attendance_delete&attendance_id=' . $attendance[0] . $param_gradebook . '">' .
Display::return_icon('delete.png', get_lang('Delete'), array(), ICON_SIZE_SMALL) . '</a>';
}
}
}
@ -346,9 +373,9 @@ class Attendance
// add link to gradebook
if ($link_to_gradebook && !empty($this->category_id)) {
$description = '';
$link_id = GradebookUtils::is_resource_in_course_gradebook($course_code, 7, $attendance_id, $session_id);
$link_id = is_resource_in_course_gradebook($course_code, 7, $attendance_id, $session_id);
if (!$link_id) {
GradebookUtils::add_resource_to_course_gradebook(
add_resource_to_course_gradebook(
$this->category_id,
$course_code,
7,
@ -409,7 +436,7 @@ class Attendance
/**
* Delete attendances
* @param int|array one or many attendances id
* @param int|array $attendance_id one or many attendances id
* @return int affected rows
*/
public function attendance_delete($attendance_id)
@ -421,19 +448,20 @@ class Attendance
if (is_array($attendance_id)) {
foreach ($attendance_id as $id) {
$id = intval($id);
$sql = "UPDATE $tbl_attendance SET active = 0
$sql = "UPDATE $tbl_attendance SET active = 2
WHERE c_id = $course_id AND id = '$id'";
Database::query($sql);
$affected_rows = Database::affected_rows();
if (!empty($affected_rows)) {
// update row item property table
api_item_property_update($_course, TOOL_ATTENDANCE, $id,"delete", $user_id);
api_item_property_update($_course, TOOL_ATTENDANCE, $id, "delete", $user_id);
}
}
} else {
$attendance_id = intval($attendance_id);
$sql = "UPDATE $tbl_attendance SET active = 0
$sql = "UPDATE $tbl_attendance SET active = 2
WHERE c_id = $course_id AND id = '$attendance_id'";
Database::query($sql);
$affected_rows = Database::affected_rows();
if (!empty($affected_rows)) {
@ -450,6 +478,58 @@ class Attendance
return $affected_rows;
}
/**
* Changes visibility
* @param int|array $attendanceId one or many attendances id
* @param status
* @return int affected rows
*/
public function changeVisibility($attendanceId, $status = 1)
{
$_course = api_get_course_info();
$tbl_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
$user_id = api_get_user_id();
$course_id = api_get_course_int_id();
$status = intval($status);
$action = 'visible';
if ($status == 0) {
$action = 'invisible';
}
if (is_array($attendanceId)) {
foreach ($attendanceId as $id) {
$id = intval($id);
$sql = "UPDATE $tbl_attendance SET active = $status
WHERE c_id = $course_id AND id = '$id'";
Database::query($sql);
$affected_rows = Database::affected_rows();
if (!empty($affected_rows)) {
// update row item property table
api_item_property_update($_course, TOOL_ATTENDANCE, $id, $action, $user_id);
}
}
} else {
$attendanceId = intval($attendanceId);
$sql = "UPDATE $tbl_attendance SET active = $status
WHERE c_id = $course_id AND id = '$attendanceId'";
Database::query($sql);
$affected_rows = Database::affected_rows();
if (!empty($affected_rows)) {
// update row item property table
api_item_property_update(
$_course,
TOOL_ATTENDANCE,
$attendanceId,
$action,
$user_id
);
}
}
return $affected_rows;
}
/**
* Lock or unlock an attendance
* @param int attendance id
@ -1520,7 +1600,6 @@ class Attendance
$sessionId = api_get_session_id();
$courseCode = api_get_course_id();
$courseId = api_get_course_int_id();
if (!empty($sessionId)) {
$users = CourseManager:: get_user_list_from_course_code(
$courseCode,
@ -1559,7 +1638,7 @@ class Attendance
}
$accessData = CourseManager::getCourseAccessPerCourseAndSession(
$courseId,
$courseCode,
$sessionId,
$dateTimeStartOriginal->format('Y-m-d H:i:s'),
$dateTimeEnd->format('Y-m-d H:i:s')

@ -106,9 +106,14 @@ class CourseManager
if (api_get_setting('gradebook_enable_grade_model') == 'true') {
//Create gradebook_category for the new course and add a gradebook model for the course
if (isset($params['gradebook_model_id']) && !empty($params['gradebook_model_id']) && $params['gradebook_model_id'] != '-1') {
GradebookUtils::create_default_course_gradebook($course_info['code'],
$params['gradebook_model_id']);
if (isset($params['gradebook_model_id']) &&
!empty($params['gradebook_model_id']) &&
$params['gradebook_model_id'] != '-1'
) {
GradebookUtils::create_default_course_gradebook(
$course_info['code'],
$params['gradebook_model_id']
);
}
}
// If parameter defined, copy the contents from a specific
@ -152,7 +157,7 @@ class CourseManager
{
return Database::fetch_array(Database::query(
"SELECT *, id as real_id FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE code='" . Database::escape_string($course_code) . "'"), 'ASSOC'
WHERE code='" . Database::escape_string($course_code) . "'"), 'ASSOC'
);
}
@ -288,9 +293,10 @@ class CourseManager
*/
public static function get_access_settings($course_code)
{
return Database::fetch_array(Database::query(
"SELECT visibility, subscribe, unsubscribe from " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE code = '" . Database::escape_string($course_code) . "'")
return Database::fetch_array(Database::query("
SELECT visibility, subscribe, unsubscribe
FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE code = '" . Database::escape_string($course_code) . "'")
);
}
@ -305,7 +311,7 @@ class CourseManager
{
$result = Database::fetch_array(Database::query(
"SELECT status FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
WHERE course_code = '" . Database::escape_string($course_code) . "' AND user_id = " . intval($user_id))
WHERE course_code = '" . Database::escape_string($course_code) . "' AND user_id = " . intval($user_id))
);
return $result['status'];
@ -431,7 +437,10 @@ class CourseManager
if (Database::num_rows($rs) == 0) {
// Delete in table session_rel_user
$sql = "DELETE FROM " . Database::get_main_table(TABLE_MAIN_SESSION_USER) . "
WHERE id_session ='" . $session_id . "' AND id_user='$uid' AND relation_type<>" . SESSION_RELATION_TYPE_RRHH . "";
WHERE
id_session ='" . $session_id . "' AND
id_user='$uid' AND
relation_type<>" . SESSION_RELATION_TYPE_RRHH . "";
Database::query($sql);
}
}
@ -527,7 +536,8 @@ class CourseManager
//$role_id = ($status == COURSEMANAGER) ? COURSE_ADMIN : NORMAL_COURSE_MEMBER;
// A preliminary check whether the user has bben already registered on the platform.
if (Database::num_rows(@Database::query("SELECT status FROM " . Database::get_main_table(TABLE_MAIN_USER) . "
if (Database::num_rows(@Database::query(
"SELECT status FROM " . Database::get_main_table(TABLE_MAIN_USER) . "
WHERE user_id = '$user_id' ")) == 0
) {
return false; // The user has not been registered to the platform.
@ -535,7 +545,8 @@ class CourseManager
// Check whether the user has not been already subscribed to the course.
if (empty($session_id)) {
if (Database::num_rows(@Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
if (Database::num_rows(@Database::query("
SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
WHERE user_id = '$user_id' AND relation_type<>" . COURSE_RELATION_TYPE_RRHH . " AND course_code = '$course_code'")) > 0
) {
return false; // The user has been already subscribed to the course.
@ -545,10 +556,12 @@ class CourseManager
if (!empty($session_id)) {
// Check whether the user has not already been stored in the session_rel_course_user table
if (Database::num_rows(@Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
WHERE course_code = '" . $course_code . "'
AND id_session ='" . $session_id . "'
AND id_user = '" . $user_id . "'")) > 0
if (Database::num_rows(@Database::query("
SELECT * FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
WHERE
course_code = '" . $course_code . "' AND
id_session ='" . $session_id . "' AND
id_user = '" . $user_id . "'")) > 0
) {
return false;
}
@ -633,7 +646,9 @@ class CourseManager
{
$t_cfv = Database::get_main_table(TABLE_MAIN_COURSE_FIELD_VALUES);
$table_field = Database::get_main_table(TABLE_MAIN_COURSE_FIELD);
$sql = "SELECT course_code FROM $table_field cf INNER JOIN $t_cfv cfv ON cfv.field_id=cf.id
$sql = "SELECT course_code
FROM $table_field cf
INNER JOIN $t_cfv cfv ON cfv.field_id=cf.id
WHERE field_variable='$original_course_id_name' AND field_value='$original_course_id_value'";
$res = Database::query($sql);
$row = Database::fetch_object($res);
@ -776,8 +791,10 @@ class CourseManager
*/
public static function get_real_course_list()
{
$sql_result = Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE target_course_code IS NULL");
$sql_result = Database::query("
SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE target_course_code IS NULL"
);
$real_course_list = array();
while ($result = Database::fetch_array($sql_result)) {
$real_course_list[$result['code']] = $result;
@ -785,21 +802,6 @@ class CourseManager
return $real_course_list;
}
/**
* Lists all virtual courses
* @return array Course info (course code => details) of all virtual courses on the platform
* @deprecated virtual course feature is not supported
*/
public static function get_virtual_course_list()
{
$sql_result = Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . " WHERE target_course_code IS NOT NULL");
$virtual_course_list = array();
while ($result = Database::fetch_array($sql_result)) {
$virtual_course_list[$result['code']] = $result;
}
return $virtual_course_list;
}
/**
* Returns an array with the course info of the real courses of which
* the current user is course admin
@ -986,182 +988,6 @@ class CourseManager
return $data;
}
/**
* Find out for which courses the user is registered and determine a visual course code and course title from that.
* Takes virtual courses into account
*
* Default case: the name and code stay what they are.
*
* Scenarios:
* - User is registered in real course and virtual courses; name / code become a mix of all
* - User is registered in real course only: name stays that of real course
* - User is registered in virtual course only: name becomes that of virtual course
* - user is not registered to any of the real/virtual courses: name stays that of real course
* (I'm not sure about the last case, but this seems not too bad)
*
* @author Roan Embrechts
* @param int $user_id , the id of the user
* @param array $course_info , an array with course info that you get using Database::get_course_info($course_system_code);
* @return array An array with indices
* $return_result['title'] - the course title of the combined courses
* $return_result['code'] - the course code of the combined courses
* @deprecated use api_get_course_info()
*/
public static function determine_course_title_from_course_info($user_id, $course_info)
{
if ($user_id != strval(intval($user_id))) {
return array();
}
$real_course_id = $course_info['system_code'];
$real_course_info = api_get_course_info($real_course_id);
$real_course_name = $real_course_info['title'];
$real_course_visual_code = $real_course_info['visual_code'];
$real_course_real_code = Database::escape_string($course_info['system_code']);
//is the user registered in the real course?
$result = Database::fetch_array(Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
WHERE user_id = '$user_id' AND relation_type<>" . COURSE_RELATION_TYPE_RRHH . " AND course_code = '$real_course_real_code'"));
$user_is_registered_in_real_course = !empty($result);
//get a list of virtual courses linked to the current real course and to which the current user is subscribed
$user_subscribed_virtual_course_list = self::get_list_of_virtual_courses_for_specific_user_and_real_course($user_id,
$real_course_id);
$virtual_courses_exist = count($user_subscribed_virtual_course_list) > 0;
//now determine course code and name
if ($user_is_registered_in_real_course && $virtual_courses_exist) {
$course_info['name'] = self::create_combined_name($user_is_registered_in_real_course, $real_course_name,
$user_subscribed_virtual_course_list);
$course_info['official_code'] = self::create_combined_code($user_is_registered_in_real_course,
$real_course_visual_code, $user_subscribed_virtual_course_list);
} elseif ($user_is_registered_in_real_course) {
//course name remains real course name
$course_info['name'] = $real_course_name;
$course_info['official_code'] = $real_course_visual_code;
} elseif ($virtual_courses_exist) {
$course_info['name'] = self::create_combined_name($user_is_registered_in_real_course, $real_course_name,
$user_subscribed_virtual_course_list);
$course_info['official_code'] = self::create_combined_code($user_is_registered_in_real_course,
$real_course_visual_code, $user_subscribed_virtual_course_list);
} else {
//course name remains real course name
$course_info['name'] = $real_course_name;
$course_info['official_code'] = $real_course_visual_code;
}
$return_result['title'] = $course_info['name'];
$return_result['code'] = $course_info['official_code'];
return $return_result;
}
/**
* Create a course title based on all real and virtual courses the user is registered in.
* @param boolean $user_is_registered_in_real_course
* @param string $real_course_name , the title of the real course
* @param array $virtual_course_list , the list of virtual courses
* @deprecated
*/
public static function create_combined_name(
$user_is_registered_in_real_course,
$real_course_name,
$virtual_course_list
) {
$complete_course_name = array();
if ($user_is_registered_in_real_course) {
// Add the real name to the result.
$complete_course_name[] = $real_course_name;
}
// Add course titles of all virtual courses.
foreach ($virtual_course_list as $current_course) {
$complete_course_name[] = $current_course['title'];
}
// 'CombinedCourse' is from course_home language file.
return (($user_is_registered_in_real_course || count($virtual_course_list) > 1) ? get_lang('CombinedCourse') . ' ' : '') . implode(' &amp; ',
$complete_course_name);
}
/**
* Create a course code based on all real and virtual courses the user is registered in.
* @deprecated
*/
public static function create_combined_code(
$user_is_registered_in_real_course,
$real_course_code,
$virtual_course_list
) {
$complete_course_code = array();
if ($user_is_registered_in_real_course) {
// Add the real code to the result
$complete_course_code[] = $real_course_code;
}
// Add codes of all virtual courses.
foreach ($virtual_course_list as $current_course) {
$complete_course_code[] = $current_course['visual_code'];
}
return implode(' &amp; ', $complete_course_code);
}
/**
* Return course info array of virtual course
*
* Note this is different from getting information about a real course!
*
* @param $real_course_code , the id of the real course which the virtual course is linked to
* @deprecated virtual courses doesn't exist anymore
*/
public static function get_virtual_course_info($real_course_code)
{
$sql_result = Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE target_course_code = '" . Database::escape_string($real_course_code) . "'");
$result = array();
while ($virtual_course = Database::fetch_array($sql_result)) {
$result[] = $virtual_course;
}
return $result;
}
/**
* @param string $system_code , the system code of the course
* @return true if the course is a virtual course, false otherwise
* @deprecated virtual courses doesn't exist anymore
*/
public static function is_virtual_course_from_system_code($system_code)
{
$result = Database::fetch_array(Database::query("SELECT target_course_code FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE code = '" . Database::escape_string($system_code) . "'"));
return !empty($result['target_course_code']);
}
/**
* Returns whether the course code given is a visual code
* @param string Visual course code
* @return true if the course is a virtual course, false otherwise
* @deprecated virtual courses doesn't exist anymore
*/
public static function is_virtual_course_from_visual_code($visual_code)
{
$result = Database::fetch_array(Database::query("SELECT target_course_code FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE visual_code = '" . Database::escape_string($visual_code) . "'"));
return !empty($result['target_course_code']);
}
/**
* @return true if the real course has virtual courses that the user is subscribed to, false otherwise
* @deprecated virtual courses doesn't exist anymore
*/
public static function has_virtual_courses_from_code($real_course_code, $user_id)
{
return count(self::get_list_of_virtual_courses_for_specific_user_and_real_course($user_id,
$real_course_code)) > 0;
}
/**
* Return an array of arrays, listing course info of all virtual course
* linked to the real course ID $real_course_code
@ -1181,21 +1007,6 @@ class CourseManager
return $result_array;
}
/**
* This function returns the course code of the real course
* to which a virtual course is linked.
* @deprecated
* @param the course code of the virtual course
* @return the course code of the real course
*/
public static function get_target_of_linked_course($virtual_course_code)
{
//get info about the virtual course
$result = Database::fetch_array(Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
WHERE code = '" . Database::escape_string($virtual_course_code) . "'"));
return $result['target_course_code'];
}
/**
* @param int $userId
* @param array $courseInfo
@ -1381,7 +1192,7 @@ class CourseManager
}
/**
* Return user info array of all users registered in the specified real or virtual course
* Return user info array of all users registered in a course
* This only returns the users that are registered in this actual course, not linked courses.
* @param string $course_code
* @param int $session_id
@ -1707,8 +1518,11 @@ class CourseManager
* @param int $session_id
* @return int
*/
public static function get_users_count_in_course($course_code, $session_id = 0)
{
public static function get_users_count_in_course(
$course_code,
$session_id = 0,
$status = null
) {
// variable initialisation
$session_id = intval($session_id);
$course_code = Database::escape_string($course_code);
@ -1794,7 +1608,7 @@ class CourseManager
}
/**
* Return user info array of all users registered in the specified real or virtual course
* Return user info array of all users registered in a course
* This only returns the users that are registered in this actual course, not linked courses.
*
* @param string $course_code
@ -1873,7 +1687,7 @@ class CourseManager
}
/**
* Return user info array of all teacher-users registered in the specified real or virtual course
* Return user info array of all teacher-users registered in a course
* This only returns the users that are registered in this actual course, not linked courses.
*
* @param string $course_code
@ -5578,15 +5392,20 @@ class CourseManager
* This function gets all the courses that are not in a session
* @param date Start date
* @param date End date
* @param bool $includeClosed Whether to include closed and hidden courses
* @return array Not-in-session courses
*/
public static function getCoursesWithoutSession($startDate = null, $endDate = null)
public static function getCoursesWithoutSession($startDate = null, $endDate = null, $includeClosed = false)
{
$dateConditional = ($startDate && $endDate) ?
" WHERE id_session IN (SELECT id FROM " . Database::get_main_table(TABLE_MAIN_SESSION) .
" WHERE date_start = '$startDate' AND date_end = '$endDate')" :
null;
$query = "SELECT id, code, title FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . " WHERE CODE NOT IN
$visibility = ($includeClosed ? '' : 'visibility NOT IN (0, 4) AND ');
$query = "SELECT id, code, title FROM " . Database::get_main_table(TABLE_MAIN_COURSE)
. " WHERE $visibility
code NOT IN
(SELECT DISTINCT course_code FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE) . $dateConditional . ")
ORDER BY id";

@ -48,12 +48,8 @@ class SessionManager
* Create a session
* @author Carlos Vargas <carlos.vargas@beeznest.com>, from existing code
* @param string name
* @param integer Start year (yyyy)
* @param integer Start month (mm)
* @param integer Start day (dd)
* @param integer End year (yyyy)
* @param integer End month (mm)
* @param integer End day (dd)
* @param string Start date (YYYY-MM-DD)
* @param string End date (YYYY-MM-DD)
* @param integer Number of days that the coach can access the session before the start date
* @param integer Number of days that the coach can access the session after the end date
* @param integer If 1, means there are no date limits

@ -462,18 +462,6 @@ class SocialManager extends UserManager
$course_visibility = $course_access_settings['visibility'];
$user_in_course_status = CourseManager :: get_user_in_course_status(api_get_user_id(), $course_code);
//function logic - act on the data
$is_virtual_course = CourseManager :: is_virtual_course_from_system_code($course_code);
if ($is_virtual_course) {
// If the current user is also subscribed in the real course to which this
// virtual course is linked, we don't need to display the virtual course entry in
// the course list - it is combined with the real course entry.
$target_course_code = CourseManager :: get_target_of_linked_course($course_code);
$is_subscribed_in_target_course = CourseManager :: is_user_subscribed_in_course(api_get_user_id(), $target_course_code);
if ($is_subscribed_in_target_course) {
return; //do not display this course entry
}
}
$s_htlm_status_icon = Display::return_icon('course.gif', get_lang('Course'));

@ -300,9 +300,16 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE;
// Change to true to restrict the visibility
//$_configuration['prevent_session_admins_to_manage_all_users'] = false;
// If there are any tool available and the user is not registered hide the group
// $_configuration['hide_course_group_if_no_tools_available'] = false;
//$_configuration['hide_course_group_if_no_tools_available'] = false;
// Attach a document to a work
// $_configuration['add_document_to_work'] = false;
//$_configuration['add_document_to_work'] = false;
// Allow user comments in work
// $_configuration['work_user_comments'] = false;
//$_configuration['work_user_comments'] = false;
// Decode UTF-8 from Web Services (option passed to SOAP)
//$_configuration['registration.soap.php.decode_utf8'] = false;
// Show delete option in attendance
//$_configuration['allow_delete_attendance'] = false;

@ -3464,8 +3464,10 @@ CREATE TABLE track_e_attempt_coeff (
);
-- Course
DROP TABLE IF EXISTS c_student_publication_rel_document;
CREATE TABLE IF NOT EXISTS c_student_publication_rel_document (id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, work_id INT NOT NULL, document_id INT NOT NULL, c_id INT NOT NULL);
DROP TABLE IF EXISTS c_student_publication_rel_user;
CREATE TABLE IF NOT EXISTS c_student_publication_rel_user ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, work_id INT NOT NULL, user_id INT NOT NULL, c_id INT NOT NULL);
DROP TABLE IF EXISTS c_student_publication_comment;
CREATE TABLE IF NOT EXISTS c_student_publication_comment ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, work_id INT NOT NULL, c_id INT NOT NULL, comment text, file VARCHAR(255), user_id int NOT NULL, sent_at datetime NOT NULL);

@ -2,8 +2,8 @@
/*
for more information: see languages.txt in the lang folder.
*/
$OpenBadgesBannerText = "A new online standard to recognize and verify learning in combination with Chamilo skills. Use the tabs to configure it.";
$OpenBadgesIntroduction = "Introducing OpenBadges";
$OpenBadgesBannerText = "You can generate badges for the skills learnt by your users, to give them recognition for their effort, through which they will be able to show off their acquired skills and competencies with icons that will be shown on their user profile. For more information on OpenBadges, check <a href='http://openbadges.org'>http://openbadges.org/</a>.";
$OpenBadgesIntroduction = "You can now design skills learning badges for learning through your courses on this virtual campus.";
$DesignANewBadgeComment = "Design a new badge, download it from the design tool and upload it on the platform.";
$TheBadgesWillBeSentToThatBackpack = "The badges will be sent to this backpack";
$BackpackDetails = "Backpack details";
@ -338,6 +338,7 @@ $WCAGGoMenu = "Goto menu";
$WCAGGoContent = "Goto content";
$NoTimeLimits = "No time limits";
$SearchXapianModuleNotInstalled = "The Xapian search module is not installed";
$OpenBadgesTitle = "Chamilo supports the OpenBadges standard";
$NoPosts = "No posts";
$WithoutAchievedSkills = "Without achieved skills";
$TypeMessage = "Please type your message!";
@ -361,6 +362,7 @@ $ClearList = "Clear the chat";
$SessionBanner = "Session banner";
$ShortDescription = "Short description";
$TargetAudience = "Target audience";
$OpenBadgesActionCall = "Convert your virtual campus to a skills-based learning experience";
$CallSent = "Chat call has been sent. Waiting for the approval of your partner.";
$ChatDenied = "Your call has been denied by your partner.";
$Send = "Send message";

@ -2,8 +2,8 @@
/*
for more information: see languages.txt in the lang folder.
*/
$OpenBadgesBannerText = "Un nouveau standard ouvert pour reconnaître et vérifier l'apprentissage, en combinaison avec les compétences de Chamilo. Utilisez les onglets pour le configurer.";
$OpenBadgesIntroduction = "Nous vous présentons OpenBadges";
$OpenBadgesBannerText = "Vous pouvez maintenant créer des insignes qui reconnaissent les compétences appris par vos utilisateurs, les récompensent pour leurs efforts et au travers desquels ils pourront démontrer leurs compétences acquises sur leur page de profil. Pour plus d'informations au sujet d'OpenBadges: <a href='http://openbadges.org'>http://openbadges.org</a>.";
$OpenBadgesIntroduction = "Vous pouvez maintenant élaborer des badges pour récompenser l'acquisition de compétences au travers des cours sur ce campus virtuel.";
$DesignANewBadgeComment = "Élaborez un nouveau badge, téléchargez-le et utilisez-le dans le formulaire du badge.";
$TheBadgesWillBeSentToThatBackpack = "Les badges seront envoyés vers ce sac à dos";
$BackpackDetails = "Détails du sac à dos";
@ -339,12 +339,29 @@ $WCAGGoMenu = "Aller au menu";
$WCAGGoContent = "Aller au contenu";
$NoTimeLimits = "Pas de limite de temps";
$SearchXapianModuleNotInstalled = "Le module de recherche Xapian n'est pas installé";
$OpenBadgesTitle = "Chamilo supporte le standard OpenBadges";
$NoPosts = "Aucune publication";
$WithoutAchievedSkills = "Aucune compétence acquise";
$TypeMessage = "Veuillez introduire votre message !";
$ConfirmReset = "Etes-vous sûr de vouloir supprimer tous les messages ?";
$MailCronCourseExpirationReminderBody = "Cher/Chère %s,
Nous avons remarqué que vous n'avez pas terminé le cours %s alors que sa date de fin a été établie au %s, vous laissant %s jour(s) pour le terminer. Nous vous rappelons que vous ne disposez de la possibilité de suivre ce cours qu'une fois par an. Nous vous invitons donc avec insistance à le compléter dans le délai qu'il vous reste. Vous pouvez retrouver le cours en vous connectant à la plate-forme à cette adresse: %s
--
Cordialement,
L'équipe de support de %s";
$MailCronCourseExpirationReminderSubject = "Urgent: Rappel d'expiration prochaine du cours %s";
$ExerciseAndLearningPath = "Exercices et parcours";
$LearningPathGradebookWarning = "Avertissement: Il est possible d'utiliser des exercices faisant partie d'un parcours dans le cahier de notes. Cependant, si le parcours lui-même est déjà inclus, cet exercice fera peut-être déjà partie de l'évaluation du parcours. L'évaluation d'un parcours se fait selon son pourcentage de progression, alors que l'évaluation d'une exercice se fait selon le score obtenu. Enfin, l'évaluation des enquêtes se fait sur base de la réponse ou non à l'enquête, ce qui signifie que le 'score' obtenu est de 0 (non répondu) ou 1 (répondu) selon les cas. Veillez à tester les combinaisons que vous organisez dans votre cahier de notes pour éviter les casse-têtes.";
$ChooseEitherDurationOrTimeLimit = "Vous devez choisir entre une durée et une période définie par des dates";
$ClearList = "Effacer la liste";
$SessionBanner = "Banner de session";
$ShortDescription = "Courte description";
$TargetAudience = "Public cible";
$OpenBadgesActionCall = "Convertissez votre campus en ligne en un lieu d'apprentissage par compétences.";
$CallSent = "Une demande de \"chat\" a été envoyée. En attente d'approbation de la personne contactée.";
$ChatDenied = "Votre appel a été refusé par la personne contactée.";
$Send = "Envoyer";
@ -440,7 +457,7 @@ $dateFormatShort = "%a %d %b %Y";
$dateFormatLong = "%A %d %B %Y";
$dateTimeFormatLong = "%A %d %B %Y à %H:%M";
$timeNoSecFormat = "%H:%M";
$Yes = "oui";
$Yes = "Oui";
$No = "Non";
$Next = "Suivant";
$Allowed = "Autorisé";

@ -2,8 +2,8 @@
/*
for more information: see languages.txt in the lang folder.
*/
$OpenBadgesBannerText = "Un nuevo estándar abierto para reconocer y verificar el aprendizaje en combinación con las competencias de Chamilo. Usa las pestañas para configurarlo.";
$OpenBadgesIntroduction = "Introduciendo OpenBadges";
$OpenBadgesBannerText = "Puede generar insignias para reconocer las habilidades aprendidas de sus usuarios, dar un reconocimiento por su logro, con lo cual ellos podrán mostrar sus capacidades y competencias adquiridas a través de emblemas, que serán visualizadas en su perfil de usuario. Para más información sobre los Open Badges en <a href=\"http://openbadges.org\">http://openbadges.org/</a>.";
$OpenBadgesIntroduction = "Ahora puede establecer reconocimiento de habilidades por aprender en cualquier curso de este campus virtual.";
$DesignANewBadgeComment = "Diseña una nueva insignia, descárgala y súbela en la plataforma.";
$TheBadgesWillBeSentToThatBackpack = "Las insignias se mandarán a esta mochila";
$BackpackDetails = "Detalles de la mochila";
@ -338,6 +338,7 @@ $WCAGGoMenu = "Ir al menú";
$WCAGGoContent = "Ir al contenido";
$NoTimeLimits = "Sin límite de tiempo";
$SearchXapianModuleNotInstalled = "El modulo Xapian de PHP no está configurado en su servidor, póngase en contacto con su administrador";
$OpenBadgesTitle = "Chamilo ahora tiene OpenBadges";
$NoPosts = "Sin publicaciones";
$WithoutAchievedSkills = "Sin competencias logradas";
$TypeMessage = "Por favor, escriba su mensaje";
@ -354,12 +355,14 @@ Saludos cordiales,
El equipo de %s";
$MailCronCourseExpirationReminderSubject = "Urgente: Recordatorio de vencimiento de curso %s";
$ExerciseAndLearningPath = "Ejercicios y lecciones";
$LearningPathGradebookWarning = "Advertencia: Es posible utilizar en una evaluación un ejercicio agregado a una lección. Sin embargo, si la lección ya está incluida, este ejercicio puede ser parte de la evaluación del curso. La evaluación de una lección se realiza de acuerdo con el porcentaje de progreso, mientras que la evaluación de un ejercicio se realiza de acuerdo con la puntuación obtenida. Por último, el resultado de las encuestas se basa en la respuesta o no de la encuesta, lo que significa que el resultado se obtiene a partir de 0 (no responde) o 1 (responde) según corresponda. Asegúrese de probar las combinaciones a organizar su Evaluación para evitar problemas.";
$ChooseEitherDurationOrTimeLimit = "Elija entre duración o límite de tiempo";
$ClearList = "Borrar la lista";
$SessionBanner = "Banner de sesión";
$ShortDescription = "Descripción corta";
$TargetAudience = "Público objetivo";
$OpenBadgesActionCall = "Convierta su campus virtual en un lugar de aprendizaje por competencia.";
$CallSent = "Una petición de chat ha sido enviada. Esperando la aprobación de la persona contactada.";
$ChatDenied = "Su llamada ha sido rechazada por la persona contactada";
$Send = "Enviar";

@ -34,16 +34,22 @@ $language_file[] = 'exercice';
// Including the global initialization file.
require_once '../inc/global.inc.php';
$current_course_tool = TOOL_LEARNPATH;
if (api_get_setting('show_glossary_in_documents') == 'ismanual' ||
api_get_setting('show_glossary_in_documents') == 'isautomatic'
) {
$htmlHeadXtra[] = '<script>
<!--
var jQueryFrameReadyConfigPath = \''.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.min.js\';
-->
</script>';
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.frameready.js" type="text/javascript" language="javascript"></script>';
$htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.highlight.js" type="text/javascript" language="javascript"></script>';
$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
$showGlossary = in_array($glossaryExtraTools, array('true', 'lp', 'exercise_and_lp'));
if ($showGlossary) {
if (api_get_setting('show_glossary_in_documents') == 'ismanual' ||
api_get_setting('show_glossary_in_documents') == 'isautomatic'
) {
$htmlHeadXtra[] = '<script>
<!--
var jQueryFrameReadyConfigPath = \'' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/jquery.min.js\';
-->
</script>';
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/jquery.frameready.js" type="text/javascript" language="javascript"></script>';
$htmlHeadXtra[] = '<script src="' . api_get_path(WEB_LIBRARY_PATH) . 'javascript/jquery.highlight.js" type="text/javascript" language="javascript"></script>';
}
}
$htmlHeadXtra[] = '<script>

@ -336,14 +336,20 @@ function LMSInitialize() {
update_toc(olms.lesson_status, olms.lms_item_id);
}
<?php if (api_get_setting('show_glossary_in_documents') == 'ismanual') { ?>
if (olms.lms_item_type == 'sco') {
<?php
$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
$showGlossary = in_array($glossaryExtraTools, array('true', 'lp', 'exercise_and_lp'));
if ($showGlossary) {
if (api_get_setting('show_glossary_in_documents') == 'ismanual') {
?>
if (olms.lms_item_type == 'sco') {
attach_glossary_into_scorm('automatic');
} else {
attach_glossary_into_scorm('manual');
}
<?php } elseif (api_get_setting('show_glossary_in_documents') == 'isautomatic') { ?>
attach_glossary_into_scorm('automatic');
} else {
attach_glossary_into_scorm('manual');
}
<?php } elseif (api_get_setting('show_glossary_in_documents') == 'isautomatic') { ?>
attach_glossary_into_scorm('automatic');
<?php } ?>
<?php } ?>
return('true');
}

@ -476,9 +476,9 @@ $(document).ready(function() {
</script>
<div id="page-back">
<div class="container-fluid">
<div class="row-fluid">
<div class="row">
<div class="span3 skill-options">
<div class="col-md-3 skill-options">
<div class="skill-home">
<a class="btn btn-large btn-block btn-success" href="{{ _p.web }}user_portal.php">{{ "ReturnToCourseList"|get_lang }}</a>
</div>
@ -573,7 +573,7 @@ $(document).ready(function() {
<!-- END ACCORDEON -->
</div>
<div id="wheel_container" class="span9">
<div id="wheel_container" class="col-md-9">
<div id="skill_wheel">
<img src="">
</div>

@ -264,8 +264,8 @@ $(document).ready(function() {
</script>
<div id="page-back">
<div class="container-fluid">
<div class="row-fluid">
<div class="span3 skill-options">
<div class="row">
<div class="col-md-3 skill-options">
<div class="skill-home">
<a class="btn btn-large btn-block btn-success" href="{{ _p.web }}user_portal.php">{{ "ReturnToCourseList"|get_lang }}</a>
</div>
@ -387,7 +387,7 @@ $(document).ready(function() {
</div>
<div id="wheel_container" class="span9">
<div id="wheel_container" class="col-md-9">
<div id="skill_wheel">
<img src="">
</div>

@ -309,10 +309,10 @@ function userCourseList()
*/
function checkUserBuy($parameter, $user, $type = 'COURSE')
{
$sql = "SELECT 1 FROM %s WHERE %s ='" . Database::escape_string($parameter) . "' AND id_user='" . intval($user) . "';";
$sql = "SELECT 1 FROM %s WHERE %s ='" . Database::escape_string($parameter) . "' AND %s ='" . intval($user) . "';";
$sql = $type === 'SESSION' ?
sprintf($sql, Database::get_main_table(TABLE_MAIN_SESSION_USER), 'id_session') :
sprintf($sql, Database::get_main_table(TABLE_MAIN_COURSE_USER), 'course_code');
sprintf($sql, Database::get_main_table(TABLE_MAIN_SESSION_USER), 'id_session', 'id_user') :
sprintf($sql, Database::get_main_table(TABLE_MAIN_COURSE_USER), 'course_code', 'user_id');
Database::query($sql);
if (Database::affected_rows() > 0) {
return true;
@ -330,7 +330,7 @@ function checkUserBuy($parameter, $user, $type = 'COURSE')
*/
function checkUserBuyTransfer($parameter, $user, $type = 'COURSE')
{
$sql = "SELECT 1 FROM %s WHERE %s ='" . Database::escape_string($parameter) . "' AND user_id='" . intval($user) . "';";
$sql = "SELECT 1 FROM %s WHERE %s ='" . Database::escape_string($parameter) . "' AND user_id ='" . intval($user) . "';";
$sql = $type === 'SESSION' ?
sprintf($sql, Database::get_main_table(TABLE_BUY_SESSION_TEMPORARY), 'session_id') :
sprintf($sql, Database::get_main_table(TABLE_BUY_COURSE_TEMPORAL), 'course_code');

@ -0,0 +1,202 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This script moves all courses to a session in the past (closing the month before)
* @package chamilo.tests.scripts
*/
/**
* Init
*/
// comment exit statement before executing
exit;
require __DIR__ . '/../../main/inc/global.inc.php';
$debug = 1;
// List of tables that will need an update
$tables = array(
'c_announcement' => array('c' => 'c_id', 's' => 'session_id'),
'c_attendance' => array('c' => 'c_id', 's' => 'session_id'),
'c_blog' => array('c' => 'c_id', 's' => 'session_id'),
'c_calendar_event' => array('c' => 'c_id', 's' => 'session_id'),
'c_chat_connected' => array('c' => 'c_id', 's' => 'session_id'),
'c_course_description' => array('c' => 'c_id', 's' => 'session_id'),
'c_document' => array('c' => 'c_id', 's' => 'session_id'),
'c_dropbox_category' => array('c' => 'c_id', 's' => 'session_id'),
'c_dropbox_file' => array('c' => 'c_id', 's' => 'session_id'),
'c_dropbox_post' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_category' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_forum' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_thread' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_thread_qualify' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_thread_qualify_log' => array('c' => 'c_id', 's' => 'session_id'),
'c_glossary' => array('c' => 'c_id', 's' => 'session_id'),
'c_group_info' => array('c' => 'c_id', 's' => 'session_id'),
'c_item_property' => array('c' => 'c_id', 's' => 'id_session'),
'c_link' => array('c' => 'c_id', 's' => 'session_id'),
'c_link_category' => array('c' => 'c_id', 's' => 'session_id'),
'c_lp' => array('c' => 'c_id', 's' => 'session_id'),
'c_lp_view' => array('c' => 'c_id', 's' => 'session_id'),
'c_notebook' => array('c' => 'c_id', 's' => 'session_id'),
'c_quiz' => array('c' => 'c_id', 's' => 'session_id'),
'c_student_publication' => array('c' => 'c_id', 's' => 'session_id'),
'c_survey' => array('c' => 'c_id', 's' => 'session_id'),
'c_survey_invitation' => array('c' => 'c_id', 's' => 'session_id'),
'c_thematic' => array('c' => 'c_id', 's' => 'session_id'),
'c_tool' => array('c' => 'c_id', 's' => 'session_id'),
'c_tool_intro' => array('c' => 'c_id', 's' => 'session_id'),
'c_wiki' => array('c' => 'c_id', 's' => 'session_id'),
'c_wiki_mailcue' => array('c' => 'c_id', 's' => 'session_id'),
'gradebook_category' => array('c' => 'course_code', 's' => 'session_id'),
//'session_rel_course',
//'session_rel_course_rel_user',
//'session_rel_user',
'track_course_ranking' => array('c' => 'c_id', 's' => 'session_id'),
'track_e_access' => array('access_cours_code' => 'c_id', 's' => 'access_session_id'),
'track_e_attempt' => array('c' => 'course_code', 's' => 'session_id'),
'track_e_course_access' => array('c' => 'course_code', 's' => 'session_id'),
'track_e_downloads' => array('c' => 'down_cours_id', 's' => 'down_session_id'),
'track_e_exercices' => array('c' => 'exe_cours_id', 's' => 'session_id'),
'track_e_item_property' => array('c' => 'course_id', 's' => 'session_id'),
'track_e_lastaccess' => array('c' => 'access_cours_code', 's' => 'access_session_id'),
'track_e_links' => array('c' => 'links_cours_id', 's' => 'links_session_id'),
'track_e_online' => array('c' => 'course', 's' => 'session_id'),
'track_e_uploads' => array('c' => 'upload_cours_id', 's' => 'upload_session_id'),
'user_rel_course_vote' => array('c' => 'c_id', 's' => 'session_id'),
);
// Users related tables. From those tables above, only a few have data related
// to users. Other data need not be changed, otherwise the resources will only
// be visible from a specific session.
$userTables = array(
'c_attendance' => array('c' => 'c_id', 's' => 'session_id'),
'c_blog' => array('c' => 'c_id', 's' => 'session_id'),
'c_calendar_event' => array('c' => 'c_id', 's' => 'session_id'),
'c_chat_connected' => array('c' => 'c_id', 's' => 'session_id'),
'c_dropbox_category' => array('c' => 'c_id', 's' => 'session_id'),
'c_dropbox_file' => array('c' => 'c_id', 's' => 'session_id'),
'c_dropbox_post' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_thread' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_thread_qualify' => array('c' => 'c_id', 's' => 'session_id'),
'c_forum_thread_qualify_log' => array('c' => 'c_id', 's' => 'session_id'),
'c_group_info' => array('c' => 'c_id', 's' => 'session_id'),
'c_lp_view' => array('c' => 'c_id', 's' => 'session_id'),
'c_notebook' => array('c' => 'c_id', 's' => 'session_id'),
'c_student_publication' => array('c' => 'c_id', 's' => 'session_id'),
'c_wiki' => array('c' => 'c_id', 's' => 'session_id'),
'c_wiki_mailcue' => array('c' => 'c_id', 's' => 'session_id'),
'gradebook_category' => array('c' => 'course_code', 's' => 'session_id'),
//'session_rel_course',
//'session_rel_course_rel_user',
//'session_rel_user',
'track_course_ranking' => array('c' => 'c_id', 's' => 'session_id'),
'track_e_access' => array('c' => 'c_id', 's' => 'access_session_id'),
'track_e_attempt' => array('c' => 'c_id', 's' => 'session_id'),
'track_e_course_access' => array('c' => 'c_id', 's' => 'session_id'),
'track_e_downloads' => array('c' => 'c_id', 's' => 'down_session_id'),
'track_e_exercices' => array('c' => 'c_id', 's' => 'session_id'),
'track_e_item_property' => array('c' => 'course_id', 's' => 'session_id'),
'track_e_lastaccess' => array('c' => 'c_id', 's' => 'access_session_id'),
'track_e_links' => array('c' => 'c_id', 's' => 'links_session_id'),
'track_e_online' => array('c' => 'c_id', 's' => 'session_id'),
'track_e_uploads' => array('c' => 'upload_cours_id', 's' => 'upload_session_id'),
'user_rel_course_vote' => array('c' => 'c_id', 's' => 'session_id'),
);
/**
* Create the sessions
* For each existing course, create a session that ends on the last day of the
* past month and starts 2 years before that.
*/
$year = date('Y');
$month = date('m');
$end = api_strtotime($year.'-'.$month.'-01 00:00:00') - 1;
$start = $end - (2*365*86400);
// Prepare a list of admin users to avoid removing their relation to the base course
$sql = 'SELECT user_id FROM admin';
$resultAdmin = Database::query($sql);
$admins = array();
while ($row = Database::fetch_assoc($resultAdmin)) {
$admins[] = $row['user_id'];
}
$res = Database::select('id, title, code', TABLE_MAIN_COURSE);
foreach ($res as $course) {
if ($debug) {
echo $course['title'] . PHP_EOL;
}
$sessionTitle = $course['title'] . ' ' . $month . '-' . $year . ' - a';
$startDate = ($year-2) . '-' . $month . '-01';
$endDate = $year . '-' . $month . '-01';
$id = SessionManager::create_session(
$sessionTitle,
$startDate,
$endDate,
0,
0,
0,
'info@contidosdixitais.com',
0,
SESSION_VISIBLE_READ_ONLY
);
while ($id == 'SessionNameAlreadyExists') {
if ($debug) {
echo "Could not create session $sessionTitle" . PHP_EOL;
}
// Increase the last letter
$sessionTitle = substr($sessionTitle, 0, -1) . chr(ord(substr($sessionTitle, -1, 1))+1);
$id = SessionManager::create_session(
$sessionTitle,
$startDate,
$endDate,
0,
0,
0,
'info@contidosdixitais.com',
0,
SESSION_VISIBLE_READ_ONLY
);
}
if ($debug) {
echo "Session $sessionTitle created with ID $id" . PHP_EOL;
}
SessionManager::add_courses_to_session($id, array($course['code']));
$resultUsers = Database::query("SELECT user_id FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER). " WHERE course_code = '" . $course['code'] . "'");
$users = array();
while ($row = Database::fetch_assoc($resultUsers)) {
$users[] = $row['user_id'];
}
if ($debug) {
echo count($users) . " users in course " . $course['title'] . " will be moved to session $id (unless they're admins)" . PHP_EOL;
}
SessionManager::subscribe_users_to_session_course($users, $id, $course['code']);
foreach ($userTables as $table => $fields) {
//c_id + course_id = int, others = char
if ($fields['c'] == 'c_id' or $fields['c'] == 'course_id') {
$sql = "UPDATE $table SET " . $fields['s'] . " = $id WHERE " . $fields['c'] . " = " . $course['id'];
} else {
$sql = "UPDATE $table SET " . $fields['s'] . " = $id WHERE " . $fields['c'] . " = '" . $course['code'] . "'";
}
if ($debug) {
echo $sql . PHP_EOL;
}
$resultChange = Database::query($sql);
}
// Now clean up by un-subscribing the user from the course itself manually
// to avoid deleting other stuff
foreach ($users as $user) {
if (in_array($user, $admins)) {
// Skip un-subscribing of admin users
continue;
}
$sql = "DELETE FROM course_rel_user WHERE user_id = $user AND course_code = '" . $course['code'] . "'";
if ($debug) {
echo $sql . PHP_EOL;
}
$resultRemove = Database::query($sql);
}
}
if ($debug) {
echo "End of moving process" . PH_EOL;
}
Loading…
Cancel
Save