Merge branch '1.11.x' into 3061

pull/3434/head
Yannick Warnier 5 years ago committed by GitHub
commit 530bee2b49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      .htaccess
  2. 3
      app/Resources/public/css/base.css
  3. 4
      composer.json
  4. 14
      main/admin/usergroups.php
  5. 8
      main/exercise/exercise.class.php
  6. 13
      main/exercise/exercise_submit.php
  7. 6
      main/exercise/overview.php
  8. 109
      main/group/group_space.php
  9. 4
      main/inc/ajax/model.ajax.php
  10. 78
      main/inc/ajax/myspace.ajax.php
  11. 4
      main/inc/lib/array.lib.php
  12. 47
      main/inc/lib/course.lib.php
  13. 8
      main/inc/lib/groupmanager.lib.php
  14. 12
      main/inc/lib/sessionmanager.lib.php
  15. 2
      main/inc/lib/tracking.lib.php
  16. 42
      main/inc/lib/usergroup.lib.php
  17. 7
      main/inc/lib/usermanager.lib.php
  18. 2
      main/lang/french/trad4all.inc.php
  19. 2
      main/lang/spanish/trad4all.inc.php
  20. 22
      main/survey/survey_invite.php
  21. 4
      main/tracking/courseLog.php
  22. 6
      main/webservices/api/v2.php
  23. 9
      plugin/ims_lti/ImsLtiPlugin.php
  24. 6
      plugin/ims_lti/multiply.php
  25. 126
      plugin/pausetraining/PauseTraining.php
  26. 10
      plugin/zoom/Entity/Meeting.php
  27. 25
      plugin/zoom/activity.php
  28. 1
      plugin/zoom/endpoint.php
  29. 10
      plugin/zoom/join_meeting.php
  30. 1
      plugin/zoom/lib/API/BaseMeetingTrait.php
  31. 6
      plugin/zoom/lib/MeetingRepository.php
  32. 78
      plugin/zoom/lib/ZoomPlugin.php
  33. 15
      plugin/zoom/meeting.php
  34. 32
      plugin/zoom/start.php
  35. 2
      plugin/zoom/view/activity.tpl
  36. 8
      src/Chamilo/CourseBundle/Entity/CGroupInfo.php
  37. 47
      tests/scripts/update_lti_chidren_tools.php

@ -88,3 +88,18 @@ AddType application/font-woff .woff .woff2
ExpiresActive On
ExpiresByType application/font-woff "access plus 1 month"
</IfModule>
# Add MOD Security exceptions against XSS Attack confusion in main/lp/*.php
# See https://github.com/chamilo/chamilo-lms/issues/3163
<IfModule mod_security.c>
<If "%{REQUEST_URI} =~ m#main/lp#">
SecRuleRemoveById 212000-212999
</If>
</IfModule>
<IfModule mod_security2.c>
<If "%{REQUEST_URI} =~ m#main/lp#">
SecRuleRemoveById 212000-212999
</If>
</IfModule>

@ -2428,7 +2428,8 @@ div.admin_section h4 {
}
.ui-search-table .ui-search-input input {
height: 25px;
border: 1px solid #CCC;
margin: 2px auto;
}
.exercise_overview_options {

@ -33,6 +33,7 @@
]
},
"require": {
"angelfqc/vimeo-api": "2.0.6",
"apereo/phpcas": "^1.3",
"brumann/polyfill-unserialize": "^1.0",
"chamilo/chash": "0.1.1",
@ -117,8 +118,7 @@
"zendframework/zend-config": "~2.6|^3.0",
"zendframework/zend-feed": "~2.6|^3.0",
"zendframework/zend-http": "~2.6|^3.0",
"zendframework/zend-soap": "~2.6|^3.0",
"angelfqc/vimeo-api": "2.0.6"
"zendframework/zend-soap": "~2.6|^3.0"
},
"require-dev": {
"behat/behat": "3.5.0",

@ -33,10 +33,10 @@ $columns = [
//Column config
$column_model = [
['name' => 'name', 'index' => 'name', 'width' => '35', 'align' => 'left'],
['name' => 'users', 'index' => 'users', 'width' => '15', 'align' => 'left'],
['name' => 'courses', 'index' => 'courses', 'width' => '15', 'align' => 'left'],
['name' => 'sessions', 'index' => 'sessions', 'width' => '15', 'align' => 'left'],
['name' => 'group_type', 'index' => 'group_type', 'width' => '15', 'align' => 'center'],
['name' => 'users', 'index' => 'users', 'width' => '15', 'align' => 'left', 'search' => 'false'],
['name' => 'courses', 'index' => 'courses', 'width' => '15', 'align' => 'left', 'search' => 'false'],
['name' => 'sessions', 'index' => 'sessions', 'width' => '15', 'align' => 'left', 'search' => 'false'],
['name' => 'group_type', 'index' => 'group_type', 'width' => '15', 'align' => 'center', 'search' => 'false'],
[
'name' => 'actions',
'index' => 'actions',
@ -44,6 +44,7 @@ $column_model = [
'align' => 'center',
'sortable' => 'false',
'formatter' => 'action_formatter',
'search' => 'false',
],
];
@ -194,6 +195,11 @@ Display::display_header();
true
);
?>
$('#usergroups').jqGrid(
'filterToolbar',
{stringResult: true, searchOnEnter: false, defaultSearch : "cn"}
);
});
</script>
<?php

@ -2252,15 +2252,11 @@ class Exercise
$form->addGroup($group, null, get_lang('ShowPreviousButton'));
}
// Attempts
$attempt_option = range(0, 10);
$attempt_option[0] = get_lang('Infinite');
$form->addElement(
'select',
'number',
'exerciseAttempts',
get_lang('ExerciseAttempts'),
$attempt_option,
null,
['id' => 'exerciseAttempts']
);

@ -880,11 +880,7 @@ $interbreadcrumb[] = [
$interbreadcrumb[] = ['url' => '#', 'name' => $objExercise->selectTitle(true)];
if (!in_array($origin, ['learnpath', 'embeddable', 'mobileapp'])) { //so we are not in learnpath tool
if (!api_is_allowed_to_session_edit()) {
Display::addFlash(
Display::return_message(get_lang('SessionIsReadOnly'), 'warning')
);
}
SessionManager::addFlashSessionReadOnly();
Display::display_header(null, 'Exercises');
} else {
@ -928,6 +924,13 @@ if ($is_visible_return['value'] == false) {
exit;
}
if (!api_is_allowed_to_session_edit()) {
if (!in_array($origin, ['learnpath', 'embeddable'])) {
Display::display_footer();
}
exit;
}
$exercise_timeover = false;
$limit_time_exists = (!empty($objExercise->start_time) || !empty($objExercise->end_time)) ? true : false;

@ -72,6 +72,8 @@ if ($time_control) {
}
if (!in_array($origin, ['learnpath', 'embeddable', 'mobileapp'])) {
SessionManager::addFlashSessionReadOnly();
Display::display_header();
} else {
$htmlHeadXtra[] = "
@ -192,6 +194,10 @@ if ($visible_return['value'] == false) {
}
}
if (!api_is_allowed_to_session_edit()) {
$exercise_url_button = null;
}
$attempts = Event::getExerciseResultsByUser(
api_get_user_id(),
$objExercise->id,

@ -32,13 +32,11 @@ $interbreadcrumb[] = [
];
/* Ensure all private groups // Juan Carlos Raña Trabado */
$forums_of_groups = get_forums_of_group($current_group);
if (!GroupManager::userHasAccessToBrowse($user_id, $current_group, api_get_session_id())) {
api_not_allowed(true);
}
/* Actions and Action links */
/*
* User wants to register in this group
*/
@ -66,7 +64,6 @@ Display::display_header(
'Group'
);
/* Introduction section (editable by course admin) */
Display::display_introduction_section(TOOL_GROUP);
echo '<div class="actions">';
@ -84,7 +81,7 @@ echo '<a href="'.api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq()
*/
$subscribe_group = '';
if (GroupManager::is_self_registration_allowed($user_id, $current_group)) {
$subscribe_group = '<a class="btn btn-default" href="'.api_get_self().'?selfReg=1&group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.
$subscribe_group = '<a class="btn btn-default" href="'.api_get_self().'?selfReg=1&group_id='.$current_group['id'].'" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;">'.
get_lang('RegIntoGroup').'</a>';
}
@ -93,7 +90,7 @@ if (GroupManager::is_self_registration_allowed($user_id, $current_group)) {
*/
$unsubscribe_group = '';
if (GroupManager :: is_self_unregistration_allowed($user_id, $current_group)) {
$unsubscribe_group = '<a class="btn btn-default" href="'.api_get_self().'?selfUnReg=1" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang("ConfirmYourChoice"), ENT_QUOTES))."'".')) return false;">'.
$unsubscribe_group = '<a class="btn btn-default" href="'.api_get_self().'?selfUnReg=1" onclick="javascript: if(!confirm('."'".addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES))."'".')) return false;">'.
get_lang('StudentUnsubscribe').'</a>';
}
echo '&nbsp;</div>';
@ -116,18 +113,16 @@ if (!empty($current_group['description'])) {
echo '<p>'.Security::remove_XSS($current_group['description']).'</p>';
}
//if (GroupManager::userHasAccessToBrowse($user_id, $this_group, $session_id)) {
// If the user is subscribed to the group or the user is a tutor of the group then
if (api_is_allowed_to_edit(false, true) ||
GroupManager::userHasAccessToBrowse($user_id, $current_group, api_get_session_id())
) {
$actions_array = [];
if (is_array($forums_of_groups)) {
if ($current_group['forum_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['forum_state']) {
foreach ($forums_of_groups as $key => $value) {
if ($value['forum_group_public_private'] == 'public' ||
($value['forum_group_public_private'] == 'private') ||
if ('public' === $value['forum_group_public_private'] ||
('private' === $value['forum_group_public_private']) ||
!empty($user_is_tutor) ||
api_is_allowed_to_edit(false, true)
) {
@ -145,7 +140,7 @@ if (api_is_allowed_to_edit(false, true) ||
}
}
if ($current_group['doc_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['doc_state']) {
// Link to the documents area of this group
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'document/document.php?'.api_get_cidreq(),
@ -153,7 +148,7 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['calendar_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['calendar_state']) {
$groupFilter = '';
if (!empty($group_id)) {
$groupFilter = "&type=course&user_id=GROUP:$group_id";
@ -165,14 +160,14 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['work_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['work_state']) {
// Link to the works area of this group
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq(),
'content' => Display::return_icon('work.png', get_lang('GroupWork'), [], 32),
];
}
if ($current_group['announcements_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['announcements_state']) {
// Link to a group-specific part of announcements
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'announcements/announcements.php?'.api_get_cidreq(),
@ -180,7 +175,7 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['wiki_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['wiki_state']) {
// Link to the wiki area of this group
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'wiki/index.php?'.api_get_cidreq().'&action=show&title=index&session_id='.api_get_session_id().'&group_id='.$current_group['id'],
@ -188,44 +183,52 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['chat_state'] != GroupManager::TOOL_NOT_AVAILABLE) {
if (GroupManager::TOOL_NOT_AVAILABLE != $current_group['chat_state']) {
// Link to the chat area of this group
if (api_get_course_setting('allow_open_chat_window')) {
$actions_array[] = [
'url' => "javascript: void(0);",
'url' => 'javascript: void(0);',
'content' => Display::return_icon('chat.png', get_lang('Chat'), [], 32),
'url_attributes' => [
'onclick' => " window.open('../chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id']."','window_chat_group_".api_get_course_id()."_".api_get_group_id()."','height=380, width=625, left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no')",
'onclick' => " window.open('../chat/chat.php?".api_get_cidreq().'&toolgroup='.$current_group['id']."','window_chat_group_".api_get_course_id().'_'.api_get_group_id()."','height=380, width=625, left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no')",
],
];
} else {
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH)."chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id'],
'url' => api_get_path(WEB_CODE_PATH).'chat/chat.php?'.api_get_cidreq().'&toolgroup='.$current_group['id'],
'content' => Display::return_icon('chat.png', get_lang('Chat'), [], 32),
];
}
}
$enabled = api_get_plugin_setting('bbb', 'tool_enable');
if ($enabled === 'true') {
if ('true' === $enabled) {
$bbb = new bbb();
if ($bbb->hasGroupSupport()) {
$actions_array[] = [
'url' => api_get_path(WEB_PLUGIN_PATH)."bbb/start.php?".api_get_cidreq(),
'url' => api_get_path(WEB_PLUGIN_PATH).'bbb/start.php?'.api_get_cidreq(),
'content' => Display::return_icon('bbb.png', get_lang('VideoConference'), [], 32),
];
}
}
$enabled = api_get_plugin_setting('zoom', 'tool_enable');
if ('true' === $enabled) {
$actions_array[] = [
'url' => api_get_path(WEB_PLUGIN_PATH).'zoom/start.php?'.api_get_cidreq(),
'content' => Display::return_icon('bbb.png', get_lang('VideoConference'), [], 32),
];
}
if (!empty($actions_array)) {
echo Display::actions($actions_array);
}
} else {
$actions_array = [];
if (is_array($forums_of_groups)) {
if ($current_group['forum_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['forum_state']) {
foreach ($forums_of_groups as $key => $value) {
if ($value['forum_group_public_private'] == 'public') {
if ('public' === $value['forum_group_public_private']) {
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'forum/viewforum.php?cidReq='.api_get_course_id().'&forum='.$value['forum_id'].'&gidReq='.Security::remove_XSS($current_group['id']).'&origin=group',
'content' => Display::return_icon(
@ -240,7 +243,7 @@ if (api_is_allowed_to_edit(false, true) ||
}
}
if ($current_group['doc_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['doc_state']) {
// Link to the documents area of this group
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'document/document.php?'.api_get_cidreq(),
@ -248,7 +251,7 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['calendar_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['calendar_state']) {
$groupFilter = '';
if (!empty($group_id)) {
$groupFilter = "&type=course&user_id=GROUP:$group_id";
@ -260,7 +263,7 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['work_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['work_state']) {
// Link to the works area of this group
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq(),
@ -268,7 +271,7 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['announcements_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['announcements_state']) {
// Link to a group-specific part of announcements
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'announcements/announcements.php?'.api_get_cidreq(),
@ -276,7 +279,7 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['wiki_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['wiki_state']) {
// Link to the wiki area of this group
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH).'wiki/index.php?'.api_get_cidreq().'&action=show&title=index&session_id='.api_get_session_id().'&group_id='.$current_group['id'],
@ -284,16 +287,16 @@ if (api_is_allowed_to_edit(false, true) ||
];
}
if ($current_group['chat_state'] == GroupManager::TOOL_PUBLIC) {
if (GroupManager::TOOL_PUBLIC == $current_group['chat_state']) {
// Link to the chat area of this group
if (api_get_course_setting('allow_open_chat_window')) {
$actions_array[] = [
'url' => "javascript: void(0);\" onclick=\"window.open('../chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id']."','window_chat_group_".api_get_course_id()."_".api_get_group_id()."','height=380, width=625, left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no') \"",
'url' => "javascript: void(0);\" onclick=\"window.open('../chat/chat.php?".api_get_cidreq().'&toolgroup='.$current_group['id']."','window_chat_group_".api_get_course_id().'_'.api_get_group_id()."','height=380, width=625, left=2, top=2, toolbar=no, menubar=no, scrollbars=yes, resizable=yes, location=no, directories=no, status=no') \"",
'content' => Display::return_icon('chat.png', get_lang('Chat'), [], 32),
];
} else {
$actions_array[] = [
'url' => api_get_path(WEB_CODE_PATH)."chat/chat.php?".api_get_cidreq()."&toolgroup=".$current_group['id'],
'url' => api_get_path(WEB_CODE_PATH).'chat/chat.php?'.api_get_cidreq().'&toolgroup='.$current_group['id'],
'content' => Display::return_icon('chat.png', get_lang('Chat'), [], 32),
];
}
@ -309,7 +312,7 @@ if (api_is_allowed_to_edit(false, true) ||
*/
$tutors = GroupManager::get_subscribed_tutors($current_group);
$tutor_info = '';
if (count($tutors) == 0) {
if (0 == count($tutors)) {
$tutor_info = get_lang('GroupNoneMasc');
} else {
$tutor_info .= '<ul class="thumbnails">';
@ -357,7 +360,7 @@ if (api_is_western_name_order()) {
$table->set_header(2, get_lang('FirstName'));
}
if (api_get_setting('show_email_addresses') == 'true' || api_is_allowed_to_edit() == 'true') {
if ('true' == api_get_setting('show_email_addresses') || 'true' == api_is_allowed_to_edit()) {
$table->set_header(3, get_lang('Email'));
$table->set_column_filter(3, 'email_filter');
$table->set_header(4, get_lang('Active'));
@ -434,15 +437,15 @@ function get_group_user_data($from, $number_of_items, $column, $direction)
$tableGroup = Database::get_course_table(TABLE_GROUP);
// Query
if (api_get_setting('show_email_addresses') === 'true') {
$sql = "SELECT user.id AS col0,
".(
if ('true' === api_get_setting('show_email_addresses')) {
$sql = 'SELECT user.id AS col0,
'.(
api_is_western_name_order() ?
"user.firstname AS col1,
user.lastname AS col2,"
'user.firstname AS col1,
user.lastname AS col2,'
:
"user.lastname AS col1,
user.firstname AS col2,"
'user.lastname AS col1,
user.firstname AS col2,'
)."
user.email AS col3
, user.active AS col4
@ -458,14 +461,14 @@ function get_group_user_data($from, $number_of_items, $column, $direction)
LIMIT $from, $number_of_items";
} else {
if (api_is_allowed_to_edit()) {
$sql = "SELECT DISTINCT
$sql = 'SELECT DISTINCT
u.id AS col0,
".(api_is_western_name_order() ?
"u.firstname AS col1,
u.lastname AS col2,"
'.(api_is_western_name_order() ?
'u.firstname AS col1,
u.lastname AS col2,'
:
"u.lastname AS col1,
u.firstname AS col2,")."
'u.lastname AS col1,
u.firstname AS col2,')."
u.email AS col3
, u.active AS col4
FROM $table_user u
@ -479,15 +482,15 @@ function get_group_user_data($from, $number_of_items, $column, $direction)
ORDER BY col$column $direction
LIMIT $from, $number_of_items";
} else {
$sql = "SELECT DISTINCT
$sql = 'SELECT DISTINCT
user.id AS col0,
".(
'.(
api_is_western_name_order() ?
"user.firstname AS col1,
user.lastname AS col2 "
'user.firstname AS col1,
user.lastname AS col2 '
:
"user.lastname AS col1,
user.firstname AS col2 "
'user.lastname AS col1,
user.firstname AS col2 '
)."
, user.active AS col3
FROM $table_user user
@ -573,6 +576,6 @@ function user_name_filter($name, $url_params, $row)
return UserManager::getUserProfileLink($userInfo);
}
if ($origin != 'learnpath') {
if ('learnpath' !== $origin) {
Display::display_footer();
}

@ -863,7 +863,7 @@ switch ($action) {
case 'get_usergroups':
$obj = new UserGroup();
$obj->protectScript();
$count = $obj->get_count();
$count = $obj->get_count($whereCondition);
break;
case 'get_usergroups_teacher':
$obj = new UserGroup();
@ -2177,7 +2177,7 @@ switch ($action) {
case 'get_usergroups':
$obj->protectScript();
$columns = ['name', 'users', 'courses', 'sessions', 'group_type', 'actions'];
$result = $obj->getUsergroupsPagination($sidx, $sord, $start, $limit);
$result = $obj->getUsergroupsPagination($sidx, $sord, $start, $limit, $whereCondition);
break;
case 'get_extra_fields':
$obj = new ExtraField($type);

@ -6,6 +6,7 @@
* Responses to AJAX calls.
*/
require_once __DIR__.'/../global.inc.php';
$action = $_GET['a'];
// Access restrictions.
@ -17,9 +18,82 @@ if (!$is_allowedToTrack) {
}
switch ($action) {
// At this date : 23/02/2017, a minor review can't determine where is used this case 'access_detail'
case 'lp_global_report':
$userId = (int) $_REQUEST['user_id'];
if (empty($userId)) {
exit;
}
$cacheAvailable = api_get_configuration_value('apc');
$table = null;
$variable = 'lp_global_report_'.$userId;
if ($cacheAvailable) {
if (apcu_exists($variable)) {
$table = apcu_fetch($variable);
}
}
if (!empty($table)) {
echo $table;
exit;
}
$sessionCategoryList = UserManager::get_sessions_by_category($userId, false);
$total = 0;
$totalAverage = 0;
$table = new HTML_Table(['class' => 'data_table']);
$row = 0;
$col = 0;
foreach ($sessionCategoryList as $category) {
$sessionList = $category['sessions'];
foreach ($sessionList as $session) {
$courses = $session['courses'];
$sessionId = $session['session_id'];
$session['session_name'];
$totalCourse = 0;
$totalSessionAverage = 0;
foreach ($courses as &$course) {
$average = Tracking::get_avg_student_progress($userId, $course['course_code'], [], $sessionId);
$totalSessionAverage += $average;
$totalCourse++;
if (false !== $average) {
$average = $average.' %';
}
$course['average'] = $average;
}
$total++;
$totalSessionAverage = round($totalSessionAverage / count($courses), 2);
$totalAverage += $totalSessionAverage;
$row++;
$table->setCellContents($row, 0, $session['session_name']);
$table->setCellContents($row, 1, $totalSessionAverage.' %');
$table->setCellContents($row, 2, '');
$row++;
foreach ($courses as &$course) {
$table->setCellContents($row, 0, $session['session_name']);
$table->setCellContents($row, 1, $course['title']);
$table->setCellContents($row, 2, $course['average']);
$row++;
}
}
}
$table->setCellContents(0, 0, get_lang('Global'));
$table->setCellContents(0, 1, round($totalAverage / $total, 2).' %');
$result = $table->toHtml();
if ($cacheAvailable) {
apcu_store($variable, $result, 60);
}
echo $result;
break;
case 'access_detail':
$user_id = intval($_REQUEST['student']);
// At this date : 23/02/2017, a minor review can't determine where is used this case 'access_detail'.
$user_id = (int) $_REQUEST['student'];
$course_code = Security::remove_XSS($_REQUEST['course']);
$type = Security::remove_XSS($_REQUEST['type']);
$range = Security::remove_XSS($_REQUEST['range']);

@ -52,11 +52,11 @@ function msort($array, $id = 'id', $order = 'desc')
$index = 0;
foreach ($array as $item) {
if ('desc' == $order) {
if ($item[$id] < $array[$lowest_id][$id]) {
if (strip_tags($item[$id]) < strip_tags($array[$lowest_id][$id])) {
$lowest_id = $index;
}
} else {
if (isset($item[$id]) && $item[$id] > $array[$lowest_id][$id]) {
if (isset($item[$id]) && strip_tags($item[$id]) > strip_tags($array[$lowest_id][$id])) {
$lowest_id = $index;
}
}

@ -6106,7 +6106,7 @@ class CourseManager
public static function getCourseUsers($filterByActive = null)
{
// This would return only the users from real courses:
$userList = self::get_user_list_from_course_code(
return self::get_user_list_from_course_code(
api_get_course_id(),
api_get_session_id(),
null,
@ -6120,8 +6120,6 @@ class CourseManager
[],
$filterByActive
);
return $userList;
}
/**
@ -6154,7 +6152,7 @@ class CourseManager
*
* @return HTML_QuickForm_element
*/
public static function addUserGroupMultiSelect(&$form, $alreadySelected)
public static function addUserGroupMultiSelect(&$form, $alreadySelected, $addShortCut = false)
{
$userList = self::getCourseUsers(true);
$groupList = self::getCourseGroups();
@ -6170,13 +6168,50 @@ class CourseManager
$result[$content['value']] = $content['content'];
}
return $form->addElement(
$multiple = $form->addElement(
'advmultiselect',
'users',
get_lang('Users'),
$result,
['select_all_checkbox' => true]
['select_all_checkbox' => true, 'id' => 'users']
);
$sessionId = api_get_session_id();
if ($addShortCut && empty($sessionId)) {
$addStudents = [];
foreach ($userList as $user) {
if ($user['status_rel'] == STUDENT) {
$addStudents[] = $user['user_id'];
}
}
if (!empty($addStudents)) {
$form->addHtml(
'<script>
$(function() {
$("#add_students").on("click", function() {
var addStudents = '.json_encode($addStudents).';
$.each(addStudents, function( index, value ) {
var option = $("#users option[value=\'USER:"+value+"\']");
if (option.val()) {
$("#users_to").append(new Option(option.text(), option.val()))
option.remove();
}
});
return false;
});
});
</script>'
);
$form->addLabel(
'',
Display::url(get_lang('AddStudent'), '#', ['id' => 'add_students', 'class' => 'btn btn-primary'])
);
}
}
return $multiple;
}
/**

@ -1569,9 +1569,9 @@ class GroupManager
}
return self::canUserSubscribe($user_id, $groupInfo);
} else {
return false;
}
return false;
}
/**
@ -1619,8 +1619,8 @@ class GroupManager
return false;
}
$table = Database::get_course_table(TABLE_GROUP_USER);
$group_id = intval($groupInfo['id']);
$user_id = intval($user_id);
$group_id = (int) $groupInfo['id'];
$user_id = (int) $user_id;
$sql = "SELECT 1 FROM $table
WHERE

@ -9674,4 +9674,16 @@ class SessionManager
return -1;
}
}
/**
* Add a warning message when session is read-only mode.
*/
public static function addFlashSessionReadOnly()
{
if (api_get_session_id() && !api_is_allowed_to_session_edit()) {
Display::addFlash(
Display::return_message(get_lang('SessionIsReadOnly'), 'warning')
);
}
}
}

@ -2557,7 +2557,7 @@ class Tracking
* [sum_of_progresses, number] if it is set to true
* @param bool $onlySeriousGame Optional. Limit average to lp on seriousgame mode
*
* @return float Average progress of the user in this course
* @return float Average progress of the user in this course from 0 to 100
*/
public static function get_avg_student_progress(
$studentId,

@ -195,11 +195,11 @@ class UserGroup extends Model
}
/**
* @param int $type
* @param string $extraWhereCondition
*
* @return int
*/
public function get_count()
public function get_count($extraWhereCondition = '')
{
$authorCondition = '';
@ -217,6 +217,7 @@ class UserGroup extends Model
INNER JOIN $this->access_url_rel_usergroup a
ON (u.id = a.usergroup_id)
WHERE access_url_id = $urlId $authorCondition
$extraWhereCondition
";
$result = Database::query($sql);
@ -230,6 +231,7 @@ class UserGroup extends Model
FROM {$this->table} a
WHERE 1 = 1
$authorCondition
AND $extraWhereCondition
";
$result = Database::query($sql);
if (Database::num_rows($result)) {
@ -1116,41 +1118,39 @@ class UserGroup extends Model
* @param int $sord
* @param int $start
* @param int $limit
* @param string $extraWhereCondition
*
* @return array
*/
public function getUsergroupsPagination($sidx, $sord, $start, $limit)
public function getUsergroupsPagination($sidx, $sord, $start, $limit, $extraWhereCondition = '')
{
$sord = in_array(strtolower($sord), ['asc', 'desc']) ? $sord : 'desc';
$start = (int) $start;
$limit = (int) $limit;
$sqlFrom = "{$this->table} u ";
$sqlWhere = '1 = 1 ';
if ($this->getUseMultipleUrl()) {
$urlId = api_get_current_access_url_id();
$from = $this->table." u
INNER JOIN {$this->access_url_rel_usergroup} a
ON (u.id = a.usergroup_id)";
$where = [' access_url_id = ?' => $urlId];
} else {
$from = $this->table.' u ';
$where = [];
$sqlFrom .= " INNER JOIN {$this->access_url_rel_usergroup} a ON (u.id = a.usergroup_id) ";
$sqlWhere .= " AND a.access_url_id = $urlId ";
}
if ($this->allowTeachers()) {
if (!api_is_platform_admin()) {
$userId = api_get_user_id();
$where = [' author_id = ?' => $userId];
$sqlWhere .= " AND author_id = $userId ";
}
}
$result = Database::select(
'u.*',
$from,
[
'where' => $where,
'order' => "name $sord",
'LIMIT' => "$start , $limit",
]
if ($extraWhereCondition) {
$sqlWhere .= " AND $extraWhereCondition ";
}
$result = Database::store_result(
Database::query("SELECT u.* FROM $sqlFrom WHERE $sqlWhere ORDER BY name $sord LIMIT $start, $limit")
);
$new_result = [];
@ -1320,7 +1320,7 @@ class UserGroup extends Model
public function save($params, $show_query = false)
{
$params['updated_at'] = $params['created_at'] = api_get_utc_datetime();
$params['group_type'] = isset($params['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
$params['group_type'] = !empty($params['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
$params['allow_members_leave_group'] = isset($params['allow_members_leave_group']) ? 1 : 0;
$groupExists = $this->usergroup_exists(trim($params['name']));
@ -1365,7 +1365,7 @@ class UserGroup extends Model
public function update($values, $showQuery = false)
{
$values['updated_on'] = api_get_utc_datetime();
$values['group_type'] = isset($values['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
$values['group_type'] = !empty($values['group_type']) ? self::SOCIAL_CLASS : self::NORMAL_CLASS;
$values['allow_members_leave_group'] = isset($values['allow_members_leave_group']) ? 1 : 0;
if (isset($values['id'])) {

@ -3471,10 +3471,7 @@ class UserManager
$coachList = SessionManager::getCoachesBySession($session_id);
$categoryStart = $row['session_category_date_start'] ? $row['session_category_date_start']->format('Y-m-d') : '';
$categoryEnd = $row['session_category_date_end'] ? $row['session_category_date_end']->format('Y-m-d') : '';
$courseList = self::get_courses_list_by_session(
$user_id,
$session_id
);
$courseList = self::get_courses_list_by_session($user_id, $session_id);
$daysLeft = SessionManager::getDayLeftInSession($row, $user_id);
// User portal filters:
@ -3856,6 +3853,7 @@ class UserManager
session_rel_course_user table if there are courses registered
to our user or not */
$sql = "SELECT DISTINCT
c.title,
c.visibility,
c.id as real_id,
c.code as course_code,
@ -3893,6 +3891,7 @@ class UserManager
if (api_is_allowed_to_create_course()) {
$sql = "SELECT DISTINCT
c.title,
c.visibility,
c.id as real_id,
c.code as course_code,

@ -3727,7 +3727,7 @@ $CertificateMinScore = "Score minimum";
$InViMod = "Dossier rendu invisible";
$ViewResult = "Visualisation des résultats";
$NoResultsInEvaluation = "Aucune note actuellement pour cette activité";
$AddStudent = "Ajout utilisateurs";
$AddStudent = "Ajouter des apprenants";
$ImportResult = "Import résultats";
$ImportFileLocation = "Importer un fichier";
$FileType = "Type de fichier";

@ -3737,7 +3737,7 @@ $CertificateMinScore = "Puntuación mínima de certificación";
$InViMod = "Este elemento ha sido ocultado";
$ViewResult = "Ver resultados";
$NoResultsInEvaluation = "Por ahora no hay resultados en la evaluación";
$AddStudent = "Añadir usuarios";
$AddStudent = "Añadir estudiantes";
$ImportResult = "Importar resultados";
$ImportFileLocation = "Ubicación del archivo a importar";
$FileType = "Tipo de fichero";

@ -61,8 +61,6 @@ if (api_is_course_admin()) {
];
}
$tool_name = get_lang('SurveyPublication');
// Displaying the header
Display::display_header($tool_name, 'Survey');
echo '<script>
@ -102,24 +100,10 @@ $form = new FormValidator(
'post',
api_get_self().'?survey_id='.$survey_id.'&'.api_get_cidreq()
);
$form->addElement('header', '', $tool_name);
// Course users
$complete_user_list = CourseManager::get_user_list_from_course_code(
api_get_course_id(),
api_get_session_id(),
'',
api_sort_by_first_name() ? 'ORDER BY firstname' : 'ORDER BY lastname'
);
$possible_users = [];
foreach ($complete_user_list as &$user) {
$possible_users[$user['user_id']] = api_get_person_name(
$user['firstname'],
$user['lastname']
);
}
$form->addHeader($tool_name);
$sessionId = api_get_session_id();
CourseManager::addUserGroupMultiSelect($form, []);
CourseManager::addUserGroupMultiSelect($form, [], true);
// Additional users
$form->addElement(

@ -908,7 +908,11 @@ if (!empty($groupList)) {
$totalLpProgress += $lpProgress;
}
if (empty($nbStudents)) {
$lpProgress = '0 %';
} else {
$lpProgress = round($totalLpProgress / $nbStudents, 2).' %';
}
$totalBestScoreAverageNotInLP = 0;
$bestScoreAverageNotInLP = 0;
if (!empty($exerciseList)) {

@ -343,15 +343,17 @@ try {
break;
case Rest::UPDATE_USER_PAUSE_TRAINING:
$allow = api_get_plugin_setting('pausetraining', 'tool_enable') === 'true';
$allowPauseFormation = api_get_plugin_setting('pausetraining', 'allow_users_to_edit_pause_formation') === 'true';
if (false === $allow || false === $allowPauseFormation) {
if (false === $allow) {
throw new Exception(get_lang('Plugin configured'));
}
if (empty($_POST['user_id'])) {
throw new Exception('user_id is required');
}
if (null === $restApi) {
throw new Exception('Check that the username and api_key are field in the request');
}
$plugin = PauseTraining::create();
$data = $plugin->updateUserPauseTraining($_POST['user_id'], $_POST);
$restResponse->setData([$data]);

@ -344,10 +344,11 @@ class ImsLtiPlugin extends Plugin
*
* @param Course $course
* @param ImsLtiTool $ltiTool
* @param bool $isVisible
*
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function addCourseTool(Course $course, ImsLtiTool $ltiTool)
public function addCourseTool(Course $course, ImsLtiTool $ltiTool, $isVisible = true)
{
$cTool = $this->createLinkToCourseTool(
$ltiTool->getName(),
@ -355,9 +356,11 @@ class ImsLtiPlugin extends Plugin
null,
self::generateToolLink($ltiTool)
);
$cTool->setTarget(
$cTool
->setTarget(
$ltiTool->getDocumentTarget() === 'iframe' ? '_self' : '_blank'
);
)
->setVisibility($isVisible);
$em = Database::getManager();
$em->persist($cTool);

@ -55,12 +55,14 @@ try {
['url' => api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=search_course', 'multiple' => true]
);
$form->addCheckBox('all_courses', '', $plugin->get_lang('AddInAllCourses'));
$form->addCheckBox('tool_visible', get_lang('SetVisible'), get_lang('ToolIsNowVisible'));
$form->addButtonExport(get_lang('Save'));
if ($form->validate()) {
$em = Database::getManager();
$formValues = $form->exportValues();
$formValues['courses'] = empty($formValues['courses']) ? [] : $formValues['courses'];
$formValues['tool_visible'] = !empty($formValues['tool_visible']);
if (!empty($formValues['all_courses'])) {
$courseList = Database::select('id', Database::get_main_table(TABLE_MAIN_COURSE));
@ -108,7 +110,8 @@ try {
$plugin->addCourseTool(
api_get_course_entity($newSelectedCourseId),
$newTool
$newTool,
$formValues['tool_visible']
);
}
}
@ -124,6 +127,7 @@ try {
$form->setDefaults(
[
'courses' => $selectedCoursesIds,
'tool_visible' => true,
]
);
$form->protect();

@ -123,8 +123,6 @@ class PauseTraining extends Plugin
$login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
$userTable = Database::get_main_table(TABLE_MAIN_USER);
$usersNotificationPerDay = [];
$users = [];
$now = api_get_utc_datetime();
if (!empty($date)) {
$now = $date;
@ -137,65 +135,94 @@ class PauseTraining extends Plugin
}
$extraFieldValue = new ExtraFieldValue('user');
foreach ($enableDaysList as $day) {
$day = (int) $day;
if (0 === $day) {
echo 'Day = 0 avoided '.PHP_EOL;
continue;
}
$hourStart = $day * 24;
$hourEnd = ($day - 1) * 24;
$date = new DateTime($now);
$date->sub(new DateInterval('PT'.$hourStart.'H'));
$hourStart = $date->format('Y-m-d H:i:s');
$sql = "SELECT u.id
FROM $userTable u
WHERE u.status <> ".ANONYMOUS." AND u.active = 1";
$rs = Database::query($sql);
$date = new DateTime($now);
$date->sub(new DateInterval('PT'.$hourEnd.'H'));
$hourEnd = $date->format('Y-m-d H:i:s');
$users = [];
while ($user = Database::fetch_array($rs)) {
$userId = $user['id'];
$sql = "SELECT
u.id as user_id,
MAX(t.logout_course_date) max_course_date,
MAX(l.logout_date) max_login_date
FROM $userTable u
INNER JOIN $track t
LEFT JOIN $track t
ON (u.id = t.user_id)
INNER JOIN $login l
LEFT JOIN $login l
ON (u.id = l.login_user_id)
WHERE
u.status <> ".ANONYMOUS." AND
u.active = 1
GROUP BY u.id
HAVING
(max_course_date BETWEEN '$hourStart' AND '$hourEnd') OR
(max_login_date BETWEEN '$hourStart' AND '$hourEnd')
u.id = $userId
LIMIT 1
";
$result = Database::query($sql);
$data = Database::fetch_array($result);
$maxCourseDate = '';
$maxLoginDate = '';
$rs = Database::query($sql);
if (!Database::num_rows($rs)) {
echo "No users to process for day $day".PHP_EOL.PHP_EOL;
continue;
// Take max date value.
if ($data) {
$maxCourseDate = $data['max_course_date'];
$maxLoginDate = $data['max_login_date'];
}
echo "Processing day $day".PHP_EOL.PHP_EOL;
while ($user = Database::fetch_array($rs)) {
$userId = $user['user_id'];
if (in_array($userId, $users)) {
continue;
$maxEndPause = null;
$pause = $extraFieldValue->get_values_by_handler_and_field_variable($userId, 'pause_formation');
if (!empty($pause) && isset($pause['value']) && 1 == $pause['value']) {
$endDate = $extraFieldValue->get_values_by_handler_and_field_variable(
$userId,
'end_pause_date'
);
if (!empty($endDate) && isset($endDate['value']) && !empty($endDate['value'])) {
$maxEndPause = $endDate['value'];
}
}
// Take max date value.
$maxCourseDate = $user['max_course_date'];
$maxLoginDate = $user['max_login_date'];
$maxDate = $maxCourseDate;
if ($maxLoginDate > $maxCourseDate) {
$maxDate = $maxLoginDate;
}
if ($maxEndPause > $maxDate) {
$maxDate = $maxEndPause;
}
if (empty($maxDate)) {
// Nothing found for that user, skip.
continue;
}
$users[$userId] = $maxDate;
}
$extraFieldValue = new ExtraFieldValue('user');
foreach ($enableDaysList as $day) {
$day = (int) $day;
if (0 === $day) {
echo 'Day = 0 avoided '.PHP_EOL;
continue;
}
$dayToCheck = $day + 1;
$hourStart = $dayToCheck * 24;
$hourEnd = ($dayToCheck - 1) * 24;
$date = new DateTime($now);
$date->sub(new DateInterval('PT'.$hourStart.'H'));
$hourStart = $date->format('Y-m-d H:i:s');
$date = new DateTime($now);
$date->sub(new DateInterval('PT'.$hourEnd.'H'));
$hourEnd = $date->format('Y-m-d H:i:s');
echo "Processing day $day: $hourStart - $hourEnd ".PHP_EOL.PHP_EOL;
foreach ($users as $userId => $maxDate) {
if (!($maxDate > $hourStart && $maxDate < $hourEnd)) {
//echo "Message skipped for user #$userId because max date found: $maxDate not in range $hourStart - $hourEnd ".PHP_EOL;
continue;
}
// Check if user has selected to pause formation.
$pause = $extraFieldValue->get_values_by_handler_and_field_variable($userId, 'pause_formation');
if (!empty($pause) && isset($pause['value']) && 1 == $pause['value']) {
@ -215,25 +242,26 @@ class PauseTraining extends Plugin
$startDate = $startDate['value'];
$endDate = $endDate['value'];
// Ignore date if is between the pause formation.
if ($now > $startDate && $now < $endDate) {
echo "Message skipped for user #$userId because today is $now and user is in pause formation between $startDate - $endDate ".PHP_EOL;
if ($startDate > $hourStart && $startDate < $hourStart) {
//echo "Message skipped for user #$userId because process date $hourStart is in start pause in $startDate - $endDate ".PHP_EOL;
continue;
}
if ($endDate > $hourEnd && $endDate < $hourEnd) {
//echo "Message skipped for user #$userId because process date $hourEnd is in start pause in $startDate - $endDate ".PHP_EOL;
continue;
} else {
echo "Message *NOT* skipped for user #$userId because today is $now and user is in pause formation between $startDate - $endDate ".PHP_EOL;
}
}
}
echo "User #$userId added to message queue because latest login is $maxDate between $hourStart AND $hourEnd".PHP_EOL;
$users[] = $userId;
$usersNotificationPerDay[$day][] = $userId;
}
}
if (!empty($usersNotificationPerDay)) {
echo 'Now processing messages ...'.PHP_EOL;
echo PHP_EOL.'Now processing messages ...'.PHP_EOL;
ksort($usersNotificationPerDay);
foreach ($usersNotificationPerDay as $day => $userList) {
@ -267,7 +295,7 @@ class PauseTraining extends Plugin
public function runCronTest()
{
$now = api_get_utc_datetime();
$days = 30;
$days = 15;
$before = new DateTime($now);
$before->sub(new DateInterval('P'.$days.'D'));

@ -86,7 +86,7 @@ class Meeting
/**
* @var CGroupInfo
* @ORM\ManyToOne(targetEntity="Chamilo\CourseBundle\Entity\CGroupInfo")
* @ORM\JoinColumn(name="group_id", referencedColumnName="id", nullable=true)
* @ORM\JoinColumn(name="group_id", referencedColumnName="iid", nullable=true)
*/
protected $group;
@ -402,6 +402,14 @@ class Meeting
return null !== $this->course;
}
/**
* @return bool
*/
public function isCourseGroupMeeting()
{
return null !== $this->course && null !== $this->group;
}
/**
* @return bool
*/

@ -10,8 +10,6 @@ require_once __DIR__.'/config.php';
$plugin = ZoomPlugin::create();
$tool_name = $plugin->get_lang('ZoomVideoConferences');
$tpl = new Template($plugin->get_lang('ZoomVideoConferences'));
$meetingId = isset($_REQUEST['meetingId']) ? (int) $_REQUEST['meetingId'] : 0;
if (empty($meetingId)) {
api_not_allowed(true);
@ -27,8 +25,31 @@ if (null === $meeting) {
if (!$plugin->userIsConferenceManager($meeting)) {
api_not_allowed(true);
}
$returnURL = 'meetings.php';
$urlExtra = '';
if ($meeting->isCourseMeeting()) {
api_protect_course_script(true);
$urlExtra = api_get_cidreq();
$returnURL = 'start.php?'.$urlExtra;
if (api_is_in_group()) {
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(),
'name' => get_lang('Groups'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(),
'name' => get_lang('GroupSpace').' '.$meeting->getGroup()->getName(),
];
}
}
$interbreadcrumb[] = [
'url' => $returnURL,
'name' => $plugin->get_lang('ZoomVideoConferences'),
];
$tpl = new Template($meeting->getMeetingId());
$tpl->assign('actions', $plugin->getToolbar());
$tpl->assign('meeting', $meeting);
$tpl->assign('url_extra', $urlExtra);
$tpl->assign('content', $tpl->fetch('zoom/view/activity.tpl'));
$tpl->display_one_col_template();

@ -6,7 +6,6 @@ use Chamilo\PluginBundle\Zoom\API\RecordingMeeting;
use Chamilo\PluginBundle\Zoom\Meeting;
use Chamilo\PluginBundle\Zoom\MeetingActivity;
use Chamilo\PluginBundle\Zoom\Recording;
use Chamilo\PluginBundle\Zoom\Registrant;
use Symfony\Component\HttpFoundation\Response;
if ('POST' !== $_SERVER['REQUEST_METHOD']) {

@ -24,6 +24,16 @@ if (null === $meeting) {
if ($meeting->isCourseMeeting()) {
api_protect_course_script(true);
if (api_is_in_group()) {
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(),
'name' => get_lang('Groups'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(),
'name' => get_lang('GroupSpace').' '.$meeting->getGroup()->getName(),
];
}
}
try {

@ -28,6 +28,5 @@ trait BaseMeetingTrait
/** @var string description */
public $agenda;
/** @var string description */
public $host_email;
}

@ -187,13 +187,9 @@ class MeetingRepository extends EntityRepository
/**
* Returns either a course's meetings or all course meetings.
*
* @param Course|null $course
* @param Session|null $session
* @param CGroupInfo|null $group
*
* @return ArrayCollection|Collection|Meeting[]
*/
public function courseMeetings($course, $group = null, $session = null)
public function courseMeetings(Course $course, CGroupInfo $group = null, Session $session = null)
{
return $this->matching(
Criteria::create()->where(

@ -634,15 +634,19 @@ class ZoomPlugin extends Plugin
* Generates a form to fast and easily create and start an instant meeting.
* On validation, create it then redirect to it and exit.
*
* @param User $user
* @param Course $course
* @param Session $session
*
* @return FormValidator
*/
public function getCreateInstantMeetingForm($user, $course, $group, $session)
{
$form = new FormValidator('createInstantMeetingForm', 'post', '', '_blank');
public function getCreateInstantMeetingForm(
User $user,
Course $course,
CGroupInfo $group = null,
Session $session = null
) {
$extraUrl = '';
if (!empty($course)) {
$extraUrl = api_get_cidreq();
}
$form = new FormValidator('createInstantMeetingForm', 'post', api_get_self().'?'.$extraUrl, '_blank');
$form->addButton('startButton', $this->get_lang('StartInstantMeeting'), 'video-camera', 'primary');
if ($form->validate()) {
try {
@ -661,17 +665,17 @@ class ZoomPlugin extends Plugin
* Generates a form to schedule a meeting.
* On validation, creates it and redirects to its page.
*
* @param User|null $user
* @param Course|null $course
* @param Session|null $session
*
* @throws Exception
*
* @return FormValidator
*/
public function getScheduleMeetingForm($user, $course = null, $group = null, $session = null)
public function getScheduleMeetingForm(User $user, Course $course = null, CGroupInfo $group = null, Session $session = null)
{
$form = new FormValidator('scheduleMeetingForm');
$extraUrl = '';
if (!empty($course)) {
$extraUrl = api_get_cidreq();
}
$form = new FormValidator('scheduleMeetingForm', 'post', api_get_self().'?'.$extraUrl);
$form->addHeader($this->get_lang('ScheduleAMeeting'));
$startTimeDatePicker = $form->addDateTimePicker('startTime', get_lang('StartTime'));
$form->setRequired($startTimeDatePicker);
@ -743,6 +747,7 @@ class ZoomPlugin extends Plugin
switch ($type) {
case 'everyone':
$user = null;
$group = null;
$course = null;
$session = null;
@ -798,7 +803,7 @@ class ZoomPlugin extends Plugin
);
}
}
api_location('meeting.php?meetingId='.$newMeeting->getMeetingId());
api_location('meeting.php?meetingId='.$newMeeting->getMeetingId().'&'.$extraUrl);
} catch (Exception $exception) {
Display::addFlash(
Display::return_message($exception->getMessage(), 'error')
@ -854,7 +859,8 @@ class ZoomPlugin extends Plugin
public function getStartOrJoinMeetingURL($meeting)
{
$status = $meeting->getMeetingInfoGet()->status;
$currentUser = api_get_user_entity(api_get_user_id());
$userId = api_get_user_id();
$currentUser = api_get_user_entity($userId);
$isGlobal = 'true' === $this->get('enableGlobalConference') && $meeting->isGlobalMeeting();
switch ($status) {
@ -892,22 +898,36 @@ class ZoomPlugin extends Plugin
}
$sessionId = api_get_session_id();
$courseCode = api_get_course_id();
if (empty($sessionId)) {
$isSubscribed = CourseManager::is_user_subscribed_in_course(
$currentUser->getId(),
api_get_course_id(),
$userId,
$courseCode,
false
);
} else {
$isSubscribed = CourseManager::is_user_subscribed_in_course(
$currentUser->getId(),
api_get_course_id(),
$userId,
$courseCode,
true,
api_get_session_id()
$sessionId
);
}
if ($isSubscribed) {
if ($meeting->isCourseGroupMeeting()) {
$groupInfo = GroupManager::get_group_properties($meeting->getGroup()->getIid(), true);
$isInGroup = GroupManager::is_user_in_group($userId, $groupInfo);
if (false === $isInGroup) {
throw new Exception($this->get_lang('YouAreNotRegisteredToThisMeeting'));
}
}
if (\Chamilo\PluginBundle\Zoom\API\Meeting::TYPE_INSTANT == $meeting->getMeetingInfoGet()->type) {
return $meeting->getMeetingInfoGet()->join_url;
}
return $this->registerUser($meeting, $currentUser)->getCreatedRegistration()->join_url;
}
@ -1131,16 +1151,12 @@ class ZoomPlugin extends Plugin
}
/**
* @param Meeting $meeting
* @param User $user
* @param bool $andFlush
*
* @throws Exception
* @throws OptimisticLockException
*
* @return Registrant
*/
private function registerUser($meeting, $user, $andFlush = true)
private function registerUser(Meeting $meeting, User $user, $andFlush = true)
{
if (empty($user->getEmail())) {
throw new Exception($this->get_lang('CannotRegisterWithoutEmailAddress'));
@ -1158,6 +1174,7 @@ class ZoomPlugin extends Plugin
->setMeetingRegistrant($meetingRegistrant)
->setCreatedRegistration($meeting->getMeetingInfoGet()->addRegistrant($meetingRegistrant));
Database::getManager()->persist($registrantEntity);
if ($andFlush) {
Database::getManager()->flush($registrantEntity);
}
@ -1269,9 +1286,6 @@ class ZoomPlugin extends Plugin
* Schedules a meeting and returns it.
* set $course, $session and $user to null in order to create a global meeting.
*
* @param User|null $user the current user, for a course meeting or a user meeting
* @param Course|null $course the course, for a course meeting
* @param Session|null $session the session, for a course meeting
* @param DateTime $startTime meeting local start date-time (configure local timezone on your Zoom account)
* @param int $duration in minutes
* @param string $topic short title of the meeting, required
@ -1283,10 +1297,10 @@ class ZoomPlugin extends Plugin
* @return Meeting meeting
*/
private function createScheduleMeeting(
$user,
$course,
$group,
$session,
User $user = null,
Course $course = null,
CGroupInfo $group = null,
Session $session = null,
$startTime,
$duration,
$topic,

@ -25,8 +25,19 @@ $urlExtra = '';
if ($meeting->isCourseMeeting()) {
api_protect_course_script(true);
$this_section = SECTION_COURSES;
$returnURL = 'start.php?'.api_get_cidreq();
$urlExtra = api_get_cidreq();
$returnURL = 'start.php?'.$urlExtra;
if (api_is_in_group()) {
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.$urlExtra,
'name' => get_lang('Groups'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.$urlExtra,
'name' => get_lang('GroupSpace').' '.$meeting->getGroup()->getName(),
];
}
}
$logInfo = [
@ -34,7 +45,7 @@ $logInfo = [
];
Event::registerLog($logInfo);
$interbreadcrumb[] = [ // used in templates
$interbreadcrumb[] = [
'url' => $returnURL,
'name' => $plugin->get_lang('ZoomVideoConferences'),
];

@ -15,12 +15,29 @@ $logInfo = [
];
Event::registerLog($logInfo);
$plugin = ZoomPlugin::create();
$tool_name = $plugin->get_lang('ZoomVideoConferences');
$tpl = new Template($tool_name);
$course = api_get_course_entity();
if (null === $course) {
api_not_allowed(true);
}
$group = api_get_group_entity();
$session = api_get_session_entity();
$plugin = ZoomPlugin::create();
if (api_is_in_group()) {
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group.php?'.api_get_cidreq(),
'name' => get_lang('Groups'),
];
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(),
'name' => get_lang('GroupSpace').' '.$group->getName(),
];
}
$tool_name = $plugin->get_lang('ZoomVideoConferences');
$tpl = new Template($tool_name);
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
$isManager = $plugin->userIsCourseConferenceManager();
@ -28,7 +45,7 @@ if ($isManager) {
switch ($action) {
case 'delete':
$meeting = $plugin->getMeetingRepository()->findOneBy(['meetingId' => $_REQUEST['meetingId']]);
if ($meeting->isCourseMeeting()) {
if ($meeting && $meeting->isCourseMeeting()) {
$plugin->deleteMeeting($meeting, api_get_self().'?'.api_get_cidreq());
}
break;
@ -45,12 +62,15 @@ if ($isManager) {
$session
)->returnForm()
);
$tpl->assign('scheduleMeetingForm', $plugin->getScheduleMeetingForm(
$tpl->assign(
'scheduleMeetingForm',
$plugin->getScheduleMeetingForm(
$user,
$course,
$group,
$session
)->returnForm());
)->returnForm()
);
}
try {

@ -2,7 +2,7 @@
{{ meeting.typeName }} {{ meeting.meetingId }}
</h4>
<a class="btn btn-primary" href="meeting.php?meetingId={{ meeting.meetingId }}">
<a class="btn btn-primary" href="meeting.php?meetingId={{ meeting.meetingId }}&{{ url_extra }}">
{{ 'Edit'|get_lang }}
</a>

@ -161,6 +161,14 @@ class CGroupInfo
*/
//protected $docAccess;
/**
* @return int
*/
public function getIid()
{
return $this->iid;
}
/**
* Set name.
*

@ -0,0 +1,47 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Update all children tools created by a LTI tool in courses.
*/
use Chamilo\PluginBundle\Entity\ImsLti\ImsLtiTool;
require __DIR__.'/../../main/inc/global.inc.php';
exit;
// Arguments
$parentLtiToolId = 1;
$visibility = 1;
$image = 'ims_lti.png';
// Processing
$em = Database::getManager();
$tblCTool = Database::get_course_table(TABLE_TOOL_LIST);
/** @var ImsLtiTool $parentLtiTool */
$parentLtiTool = $em->find('ChamiloPluginBundle:ImsLti\ImsLtiTool', $parentLtiToolId);
if (!$parentLtiTool) {
exit("LTI tool ($parentLtiToolId) not found.".PHP_EOL);
}
echo "Updating children tools for parent {$parentLtiTool->getId()}:".PHP_EOL;
$childrenLtiTools = $parentLtiTool->getChildren();
/** @var ImsLtiTool $childrenLtiTool */
foreach ($childrenLtiTools as $childrenLtiTool) {
$sql = "UPDATE $tblCTool
SET visibility = $visibility,
image = '$image'
WHERE link = 'ims_lti/start.php?id={$childrenLtiTool->getId()}'
AND category = 'plugin'";
Database::query($sql);
echo "\tLTI tool updated: {$childrenLtiTool->getId()}".PHP_EOL;
}
echo "Done.".PHP_EOL;
Loading…
Cancel
Save