Update from 1.11.x

pull/2944/head
Julio Montoya 6 years ago
parent 3b3f8234dc
commit 8690b88f0a
  1. 10
      main/admin/questions.php
  2. 12
      main/admin/statistics/index.php
  3. 38
      main/announcements/announcements.php
  4. 7
      main/cron/import_csv.php
  5. 89
      main/exercise/hotspot_admin.inc.php
  6. 2
      main/gradebook/lib/be/category.class.php
  7. 4
      main/gradebook/lib/be/exerciselink.class.php
  8. 5
      main/gradebook/lib/scoredisplay.class.php
  9. 4
      main/group/group.php
  10. 9
      main/group/group_category.php
  11. 4
      main/group/group_creation.php
  12. 2
      main/group/member_settings.php
  13. 45
      main/group/settings.php
  14. 8
      main/inc/ajax/announcement.ajax.php
  15. 72
      main/inc/lib/AnnouncementManager.php
  16. 23
      main/inc/lib/api.lib.php
  17. 60
      main/inc/lib/certificate.lib.php
  18. 48
      main/inc/lib/course.lib.php
  19. 4
      main/inc/lib/course_home.lib.php
  20. 24
      main/inc/lib/formvalidator/Element/DateRangePicker.php
  21. 20
      main/inc/lib/groupmanager.lib.php
  22. 229
      main/inc/lib/javascript/chat/css/chat.css
  23. 38
      main/inc/lib/javascript/chat/js/chat.js
  24. 11
      main/inc/lib/javascript/ckeditor/plugins/qmarkersrolls/dialogs/qmarkersrolls.js
  25. 416
      main/inc/lib/javascript/jquery.frameready.js
  26. 1315
      main/inc/lib/javascript/map/markerclusterer.js
  27. 28
      main/inc/lib/javascript/map/oms.min.js
  28. 23
      main/inc/lib/pdf.lib.php
  29. 107
      main/inc/lib/pear/HTML/QuickForm.php
  30. 24
      main/inc/lib/pear/HTML/QuickForm/input.php
  31. 20
      main/inc/lib/social.lib.php
  32. 131
      main/inc/lib/statistics.lib.php
  33. 8
      main/inc/lib/tracking.lib.php
  34. 22
      main/link/link.php
  35. 97
      main/lp/learnpath.class.php
  36. 4
      main/lp/lp_add_audio.php
  37. 2
      main/lp/lp_add_category.php
  38. 10
      main/lp/lp_controller.php
  39. 2
      main/lp/lp_stats.php
  40. 12
      main/messages/new_message.php
  41. 243
      main/mySpace/lp_tracking.php
  42. 243
      main/mySpace/session.php
  43. 8
      main/mySpace/works_in_session_report.php
  44. 54
      main/session/add_courses_to_session.php
  45. 28
      main/session/add_users_to_session.php
  46. 158
      main/session/session_category_list.php
  47. 32
      main/session/session_list.php
  48. 30
      main/social/download_my_files.php
  49. 5
      main/social/home.php
  50. 6
      main/social/my_skills_report.php

@ -39,8 +39,8 @@ $questionCount = 0;
if ($formSent) {
$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : '';
$description = isset($_REQUEST['description']) ? Security::remove_XSS($_REQUEST['description']) : '';
$title = isset($_REQUEST['title']) ? Security::remove_XSS($_REQUEST['title']) : '';
$description = isset($_REQUEST['description']) ? $_REQUEST['description'] : '';
$title = isset($_REQUEST['title']) ? $_REQUEST['title'] : '';
$page = isset($_GET['page']) && !empty($_GET['page']) ? (int) $_GET['page'] : 1;
$em = Database::getManager();
@ -51,7 +51,7 @@ if ($formSent) {
}
if (!empty($description)) {
$criteria->orWhere($criteria->expr()->contains('description', "%$description%"));
$criteria->orWhere($criteria->expr()->contains('description', $description."\r"));
}
if (!empty($title)) {
@ -65,8 +65,8 @@ if ($formSent) {
}
$params = [
'id' => $id,
'title' => $title,
'description' => $description,
'title' => Security::remove_XSS($title),
'description' => Security::remove_XSS($description),
'form_sent' => 1,
];
$url = api_get_self().'?'.http_build_query($params);

@ -130,6 +130,10 @@ if ($report == 'user_session') {
$htmlHeadXtra[] = api_get_jqgrid_js();
}
if (isset($_GET['export'])) {
ob_start();
}
$tool_name = get_lang('Statistics');
Display::display_header($tool_name);
echo Display::page_header($tool_name);
@ -153,6 +157,7 @@ $tools[$strUsers]['report=logins&type=month'] = get_lang('Logins').' ('.get_
$tools[$strUsers]['report=logins&type=day'] = get_lang('Logins').' ('.get_lang('PeriodDay').')';
$tools[$strUsers]['report=logins&type=hour'] = get_lang('Logins').' ('.get_lang('PeriodHour').')';
$tools[$strUsers]['report=pictures'] = get_lang('CountUsers').' ('.get_lang('UserPicture').')';
$tools[$strUsers]['report=logins_by_date'] = get_lang('LoginsByDate');
$tools[$strUsers]['report=no_login_users'] = get_lang('StatsUsersDidNotLoginInLastPeriods');
$tools[$strUsers]['report=zombies'] = get_lang('Zombies');
@ -370,6 +375,13 @@ switch ($report) {
$friends = Statistics::getFriends();
Statistics::printStats(get_lang('CountFriends'), $friends);
break;
case 'logins_by_date':
Statistics::printLoginsByDate();
break;
}
Display::display_footer();
if (isset($_GET['export'])) {
ob_end_clean();
}

@ -37,6 +37,7 @@ $allowToEdit = (
api_is_allowed_to_edit(false, true) ||
(api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous())
);
$allowStudentInGroupToSend = false;
$sessionId = api_get_session_id();
$drhHasAccessToSessionContent = api_drh_can_access_all_session_content();
@ -60,15 +61,16 @@ $tbl_courses = Database::get_main_table(TABLE_MAIN_COURSE);
$tbl_sessions = Database::get_main_table(TABLE_MAIN_SESSION);
$tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT);
$tbl_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
$isTutor = false;
if (!empty($group_id)) {
$groupProperties = GroupManager:: get_group_properties($group_id);
$groupProperties = GroupManager::get_group_properties($group_id);
$interbreadcrumb[] = [
'url' => api_get_path(WEB_CODE_PATH)."group/group.php?".api_get_cidreq(),
'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(),
'url' => api_get_path(WEB_CODE_PATH).'group/group_space.php?'.api_get_cidreq(),
'name' => get_lang('GroupSpace').' '.$groupProperties['name'],
];
@ -78,10 +80,14 @@ if (!empty($group_id)) {
if ($isTutor) {
$allowToEdit = true;
}
// Last chance ... students can send announcements
if ($groupProperties['announcements_state'] == GroupManager::TOOL_PRIVATE_BETWEEN_USERS) {
$allowStudentInGroupToSend = true;
}
}
}
/* Tracking */
Event::event_access_tool(TOOL_ANNOUNCEMENT);
$announcement_id = isset($_GET['id']) ? (int) $_GET['id'] : null;
@ -166,9 +172,11 @@ switch ($action) {
'url' => api_get_path(WEB_CODE_PATH).'announcements/announcements.php?'.api_get_cidreq(),
'name' => $nameTools,
];
$nameTools = get_lang('View');
$content = AnnouncementManager::displayAnnouncement($announcement_id);
if (empty($content)) {
api_not_allowed(true);
}
break;
case 'list':
$htmlHeadXtra[] = api_get_jqgrid_js();
@ -291,20 +299,22 @@ switch ($action) {
if (empty($count)) {
$html = '';
if ($allowToEdit && (empty($_GET['origin']) || $_GET['origin'] !== 'learnpath')) {
$html .= '<div id="no-data-view" class="tool-view">';
if (($allowToEdit || $allowStudentInGroupToSend) &&
(empty($_GET['origin']) || $_GET['origin'] !== 'learnpath')
) {
$html .= '<div id="no-data-view">';
$html .= '<h3>'.get_lang('Announcements').'</h3>';
$html .= Display::return_icon('valves.png', '', [], 64);
$html .= '<div class="controls">';
$html .= Display::url(
get_lang('Add Announcement'),
get_lang('AddAnnouncement'),
api_get_self()."?".api_get_cidreq()."&action=add",
['class' => 'btn btn-primary']
);
$html .= '</div>';
$html .= '</div>';
} else {
$html = Display::return_message(get_lang('No Announcements'), 'warning');
$html = Display::return_message(get_lang('NoAnnouncements'), 'warning');
}
$content = $html;
} else {
@ -389,8 +399,10 @@ switch ($action) {
api_not_allowed(true);
}
if (!$allowToEdit) {
api_not_allowed(true);
if ($allowStudentInGroupToSend === false) {
if (!$allowToEdit) {
api_not_allowed(true);
}
}
// DISPLAY ADD ANNOUNCEMENT COMMAND
@ -768,7 +780,7 @@ if (empty($_GET['origin']) || $_GET['origin'] !== 'learnpath') {
// Actions
$show_actions = false;
$actionsLeft = '';
if ($allowToEdit && (empty($_GET['origin']) || $_GET['origin'] !== 'learnpath')) {
if (($allowToEdit || $allowStudentInGroupToSend) && (empty($_GET['origin']) || $_GET['origin'] !== 'learnpath')) {
if (in_array($action, ['add', 'modify', 'view'])) {
$actionsLeft .= "<a href='".api_get_self()."?".api_get_cidreq()."'>".
Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).
@ -788,7 +800,7 @@ if ($allowToEdit && (empty($_GET['origin']) || $_GET['origin'] !== 'learnpath'))
if ($allowToEdit && api_get_group_id() == 0) {
$allow = api_get_configuration_value('disable_delete_all_announcements');
if ($allow === false) {
if ($allow === false && api_is_allowed_to_edit()) {
if (!isset($_GET['action']) ||
isset($_GET['action']) && $_GET['action'] == 'list'
) {

@ -826,7 +826,7 @@ class ImportCsv
$userInfoByOfficialCode = api_get_user_info_from_official_code($row['official_code']);
}
$userInfoFromUsername = api_get_user_info_from_official_code($row['username']);
$userInfoFromUsername = api_get_user_info_from_username($row['username']);
if (!empty($userInfoFromUsername)) {
$extraFieldValue = new ExtraFieldValue('user');
$extraFieldValues = $extraFieldValue->get_values_by_handler_and_field_variable(
@ -842,11 +842,12 @@ class ImportCsv
if (!empty($user_id) && $value != $user_id) {
$emails = api_get_configuration_value('cron_notification_help_desk');
if (!empty($emails)) {
$this->logger->addInfo('Preparing email to users in configuration: "cron_notification_help_desk"');
$subject = 'User not added due to same username';
$body = 'Cannot add username: "'.$row['username'].'"
with external_user_id: '.$row['extra_'.$this->extraFieldIdNameList['user']].'
because '.$userInfoFromUsername['username'].' with external_user_id '.$value.' exists on the portal
';
because '.$userInfoFromUsername['username'].' with external_user_id '.$value.' exists on the portal';
$this->logger->addInfo($body);
foreach ($emails as $email) {
api_mail_html('', $email, $subject, $body);
}

@ -9,7 +9,7 @@ use ChamiloSession as Session;
*
* @package chamilo.exercise
*
* @author Toon Keppens
* @author Toon Keppens
*/
$modifyAnswers = (int) $_GET['hotspotadmin'];
@ -576,13 +576,14 @@ if (isset($modifyAnswers)) {
echo Display::return_message($msgErr, 'normal'); //main API
}
$hotspot_admin_url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?'.api_get_cidreq().'&hotspotadmin='.$modifyAnswers.'&exerciseId='.$exerciseId; ?>
$hotspot_admin_url = api_get_path(WEB_CODE_PATH).'exercise/admin.php?'.api_get_cidreq().'&'
.http_build_query(['hotspotadmin' => $modifyAnswers, 'exerciseId' => $exerciseId]); ?>
<form method="post" action="<?php echo $hotspot_admin_url; ?>" class="form-horizontal" id="frm_exercise"
name="frm_exercise">
<div class="form-group">
<div class="col-sm-12">
<?php if ($answerType == HOT_SPOT_DELINEATION) {
?>
?>
<button type="submit" class="btn btn-danger" name="lessAnswers" value="lessAnswers">
<em class="fa fa-trash"></em> <?php echo get_lang('LessOAR'); ?>
</button>
@ -590,8 +591,8 @@ if (isset($modifyAnswers)) {
<em class="fa fa-plus"></em> <?php echo get_lang('MoreOAR'); ?>
</button>
<?php
} else {
?>
} else {
?>
<button type="submit" class="btn btn-danger" name="lessAnswers" value="lessAnswers">
<em class="fa fa-trash"></em> <?php echo get_lang('LessHotspots'); ?>
</button>
@ -599,7 +600,7 @@ if (isset($modifyAnswers)) {
<em class="fa fa-plus"></em> <?php echo get_lang('MoreHotspots'); ?>
</button>
<?php
} ?>
} ?>
<button type="submit" class="btn btn-primary" name="submitAnswers" value="submitAnswers">
<em class="fa fa-save"></em> <?php echo get_lang('AddQuestionToExercise'); ?>
</button>
@ -662,7 +663,8 @@ if (isset($modifyAnswers)) {
foreach ($question_list as $key => $questionid) {
$selected = '';
$question = Question::read($questionid);
$val = 'Q'.$key.' :'.substrwords($question->selectTitle(), ICON_SIZE_SMALL);
$questionTitle = strip_tags($question->selectTitle());
$val = "Q$key: $questionTitle";
if (isset($select_question[$i]) && $questionid == $select_question[$i]) {
$selected = 'selected="selected"';
@ -740,8 +742,8 @@ if (isset($modifyAnswers)) {
<div class="checkbox">
<p>
<label>
<input type="checkbox" class="checkbox"
name="<?php echo 'try['.$i; ?>]" <?php if ($try[$i] == 1) {
<input type="checkbox" class="checkbox" name="<?php echo 'try['.$i; ?>]"
<?php if ($try[$i] == 1) {
echo 'checked';
} ?> />
<?php echo get_lang('TryAgain'); ?>
@ -766,7 +768,7 @@ if (isset($modifyAnswers)) {
</select>
</p>
</td>
<?php
<?php
} else {
?>
<td> &nbsp;</td>
@ -833,11 +835,11 @@ if (isset($modifyAnswers)) {
</tr>
</table>
</td>
<?php
<?php
} else {
?>
<td>&nbsp;</td>
<?php
<?php
} ?>
</tr>
<?php
@ -854,15 +856,15 @@ if (isset($modifyAnswers)) {
<th><?php if ($answerType == HOT_SPOT_DELINEATION) {
echo get_lang('Scenario');
} ?></th>
<?php
<?php
} else {
?>
<th colspan="3"><?php echo get_lang('Comment'); ?></th>
<?php
<?php
} ?>
<th>&nbsp;</th>
</tr>
<?php
<?php
} ?>
<tr>
<td>
@ -871,15 +873,12 @@ if (isset($modifyAnswers)) {
</td>
<td>
<input class="form-control" type="text" name="reponse[<?php echo $i; ?>]"
value="<?php echo isset($reponse[$i])
? Security::remove_XSS($reponse[$i])
: ''; ?>"/>
value="<?php echo isset($reponse[$i]) ? Security::remove_XSS($reponse[$i]) : ''; ?>"/>
</td>
<td colspan="2" align="left">
<textarea class="form-control" wrap="virtual" rows="3" cols="25"
name="comment[<?php echo $i; ?>]"
style="width: 100%"><?php echo isset($comment[$i])
? Security::remove_XSS($comment[$i]) : ''; ?></textarea>
style="width: 100%"><?php echo isset($comment[$i]) ? Security::remove_XSS($comment[$i]) : ''; ?></textarea>
<input type="hidden" name="hotspot_type[<?php echo $i; ?>]" value="oar"/>
<input type="hidden" name="hotspot_coordinates[<?php echo $i; ?>]" value="<?php
echo empty($hotspot_coordinates[$i]) ? '0;0|0|0' : $hotspot_coordinates[$i]; ?>"/>
@ -891,9 +890,7 @@ if (isset($modifyAnswers)) {
<p>
<label>
<input type="checkbox" class="checkbox"
name="<?php echo 'try['.$i; ?>]" <?php if (isset($try[$i])
&& $try[$i] == 1
) {
name="<?php echo 'try['.$i; ?>]" <?php if (isset($try[$i]) && $try[$i] == 1) {
echo 'checked';
} ?> />
<?php echo get_lang('TryAgain'); ?>
@ -918,7 +915,7 @@ if (isset($modifyAnswers)) {
</select>
</p>
</td>
<?php
<?php
} else {
?>
<td>&nbsp;</td>
@ -948,15 +945,13 @@ if (isset($modifyAnswers)) {
$renderer = $form->defaultRenderer();
$form_template = '{content}';
$renderer->setFormTemplate($form_template);
$element_template = '
{label}
{element}';
$element_template = '{label} {element}';
$renderer->setElementTemplate($element_template);
$form->setDefaults(['comment['.$i.']' => $commentValue]);
$return = $form->returnForm(); ?>
<td colspan="2" align="left"><?php echo $return; ?></td>
<?php
<?php
} ?>
<td>
<?php
@ -964,7 +959,7 @@ if (isset($modifyAnswers)) {
if ($_SESSION['tmp_answers']['hotspot_type'][$i] == 'oar') {
?>
<input type="hidden" name="weighting[<?php echo $i; ?>]" class="form-cotrol" value="0"/>
<?php
<?php
} else {
?>
<input class="form-control" type="text" name="weighting[<?php echo $i; ?>]"
@ -982,7 +977,7 @@ if (isset($modifyAnswers)) {
: $hotspot_coordinates[$i]; ?>"/>
<input type="hidden" name="hotspot_type[<?php echo $i; ?>]"
value="<?php echo empty($hotspot_type[$i]) ? 'square' : $hotspot_type[$i]; ?>"/>
<?php
<?php
} ?>
</td>
</tr>
@ -1017,7 +1012,8 @@ if (isset($modifyAnswers)) {
foreach ($question_list as $key => $questionid) {
$selected = '';
$question = Question::read($questionid);
$val = 'Q'.$key.' :'.substrwords($question->selectTitle(), ICON_SIZE_SMALL);
$questionTitle = $question->selectTitle();
$val = "Q$key: $questionTitle";
if ($questionid == $selectQuestionNoError) {
$selected = 'selected="selected"';
}
@ -1051,7 +1047,7 @@ if (isset($modifyAnswers)) {
</td>
<td colspan="2" align="left">
<textarea class="form-control" wrap="virtual" rows="3" cols="25"
name="comment_noerror"><?php echo Security::remove_XSS($comment_noerror); ?></textarea>
name="comment_noerror"><?php echo Security::remove_XSS($comment_noerror); ?></textarea>
</td>
<?php if ($objExercise->selectFeedbackType() == EXERCISE_FEEDBACK_TYPE_DIRECT) {
?>
@ -1103,30 +1099,29 @@ if (isset($modifyAnswers)) {
$swf_loaded = $answerType == HOT_SPOT_DELINEATION ? 'hotspot_delineation_admin' : 'hotspot_admin';
$height = 450;
$relPath = api_get_path(WEB_CODE_PATH); ?>
<div id="hotspot-container" class="center-block">
</div>
<div id="hotspot-container" class="center-block"></div>
</div>
</div>
</form>
<script>
$(function() {
$(function () {
<?php if ($answerType == HOT_SPOT_DELINEATION) {
?>
new DelineationQuestion({
questionId: <?php echo $modifyAnswers; ?>,
selector: '#hotspot-container',
for: 'admin',
relPath: '<?php echo $relPath; ?>'
});
new DelineationQuestion({
questionId: <?php echo $modifyAnswers; ?>,
selector: '#hotspot-container',
for: 'admin',
relPath: '<?php echo $relPath; ?>'
});
<?php
} else {
?>
new HotspotQuestion({
questionId: <?php echo $modifyAnswers; ?>,
selector: '#hotspot-container',
for: 'admin',
relPath: '<?php echo $relPath; ?>'
});
new HotspotQuestion({
questionId: <?php echo $modifyAnswers; ?>,
selector: '#hotspot-container',
for: 'admin',
relPath: '<?php echo $relPath; ?>'
});
<?php
} ?>
});

@ -393,7 +393,7 @@ class Category implements GradebookItem
$courseId = api_get_course_int_id();
$courseInfo = api_get_course_info_by_id($courseId);
$courseCode = $courseInfo['code'];
$session_id = intval($session_id);
$session_id = (int) $session_id;
if (!empty($session_id)) {
$table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);

@ -57,10 +57,10 @@ class ExerciseLink extends AbstractLink
// @todo
$uploadPath = null;
$sql = 'SELECT id,title FROM '.$exerciseTable.'
$sql = 'SELECT iid, title FROM '.$exerciseTable.'
WHERE c_id = '.$this->course_id.' AND active=1 '.$session_condition;
$sqlLp = "SELECT e.id, e.title
$sqlLp = "SELECT e.iid, e.title
FROM $exerciseTable e
INNER JOIN $lpItemTable i
ON (e.c_id = i.c_id AND e.id = i.path)

@ -307,6 +307,11 @@ class ScoreDisplay
return Display::bar_progress($percentage);
}
if ($type == SCORE_NUMERIC) {
$percentage = $my_score[0] / $my_score[1] * 100;
return round($percentage);
}
if ($type == SCORE_SIMPLE) {
$simpleScore = $this->format_score($my_score[0], $ignoreDecimals);

@ -44,7 +44,7 @@ $nameTools = get_lang('GroupManagement');
/*
* Self-registration and un-registration
*/
$my_group_id = isset($_GET['group_id']) ? intval($_GET['group_id']) : null;
$my_group_id = isset($_GET['group_id']) ? (int) $_GET['group_id'] : null;
$my_group = isset($_REQUEST['group']) ? Security::remove_XSS($_REQUEST['group']) : null;
$my_get_id1 = isset($_GET['id1']) ? Security::remove_XSS($_GET['id1']) : null;
$my_get_id2 = isset($_GET['id2']) ? Security::remove_XSS($_GET['id2']) : null;
@ -246,7 +246,7 @@ if (api_get_setting('allow_group_categories') === 'true') {
if (api_is_allowed_to_edit(false, true) && !empty($categoryId) && empty($sessionId)) {
// Edit
$actions .= '<a href="group_category.php?'.api_get_cidreq().'&id='.$categoryId.'" title="'.get_lang('Edit').'">'.
Display::return_icon('edit.png', get_lang('EditGroup'), '', ICON_SIZE_SMALL).'</a>';
Display::return_icon('edit.png', get_lang('EditCategory'), '', ICON_SIZE_SMALL).'</a>';
// Delete
$actions .= Display::url(

@ -53,10 +53,10 @@ function check_max_number_of_members($value)
*/
function check_groups_per_user($value)
{
$groups_per_user = $value['groups_per_user'];
$groups_per_user = (int) $value['groups_per_user'];
if (isset($_POST['id']) &&
intval($groups_per_user) != GroupManager::GROUP_PER_MEMBER_NO_LIMIT &&
GroupManager::get_current_max_groups_per_user($_POST['id']) > intval($groups_per_user)) {
$groups_per_user != GroupManager::GROUP_PER_MEMBER_NO_LIMIT &&
GroupManager::get_current_max_groups_per_user($_POST['id']) > $groups_per_user) {
return false;
}
@ -127,8 +127,9 @@ for ($i = 1; $i <= 10; $i++) {
$possible_values[$i] = $i;
}
$possible_values[GroupManager::GROUP_PER_MEMBER_NO_LIMIT] = get_lang('All');
$group = [
$form->createElement('select', 'groups_per_user', null, $possible_values),
$form->createElement('select', 'groups_per_user', null, $possible_values, ['id' => 'groups_per_user']),
$form->createElement('static', null, null, get_lang('QtyOfUserCanSubscribe_PartAfterNumber')),
];
$form->addGroup($group, 'limit_group', get_lang('QtyOfUserCanSubscribe_PartBeforeNumber'), null, false);

@ -134,7 +134,7 @@ if (isset($_POST['number_of_groups'])) {
<?php
}
$group_categories = GroupManager::get_categories();
$group_id = GroupManager:: get_number_of_groups() + 1;
$group_id = GroupManager::get_number_of_groups() + 1;
$cat_options = [];
foreach ($group_categories as $index => $category) {
$cat_options[$category['id']] = $category['title'];
@ -233,7 +233,7 @@ EOT;
$form->addGroup($group_el, 'group_'.$group_number, null, '</td><td>', false);
}
$defaults['action'] = 'create_groups';
$defaults['number_of_groups'] = intval($_POST['number_of_groups']);
$defaults['number_of_groups'] = (int) $_POST['number_of_groups'];
$form->setDefaults($defaults);
$form->addButtonCreate(get_lang('CreateGroup'), 'submit');
$form->display();

@ -209,6 +209,8 @@ if ($form->validate()) {
// Returning to the group area (note: this is inconsistent with the rest of chamilo)
$cat = GroupManager::get_category_from_group($current_group['iid']);
$max_member = $current_group['max_student'];
if (isset($_POST['group_members']) &&
count($_POST['group_members']) > $max_member &&
$max_member != GroupManager::MEMBER_PER_GROUP_NO_LIMIT

@ -21,12 +21,16 @@ api_protect_course_script(true);
$group_id = api_get_group_id();
$current_group = GroupManager::get_group_properties($group_id);
if (empty($current_group)) {
api_not_allowed(true);
}
$nameTools = get_lang('EditGroup');
$interbreadcrumb[] = ['url' => 'group.php?'.api_get_cidreq(), 'name' => get_lang('Groups')];
$interbreadcrumb[] = ['url' => 'group_space.php?'.api_get_cidreq(), 'name' => $current_group['name']];
$is_group_member = GroupManager::is_tutor_of_group(api_get_user_id(), $current_group);
$groupMember = GroupManager::is_tutor_of_group(api_get_user_id(), $current_group);
if (!api_is_allowed_to_edit(false, true) && !$is_group_member) {
if (!$groupMember && !api_is_allowed_to_edit(false, true)) {
api_not_allowed(true);
}
@ -67,8 +71,21 @@ $form->addElement('html', '<div class="col-md-6">');
// Members per group
$group = [
$form->createElement('radio', 'max_member_no_limit', get_lang('GroupLimit'), get_lang('NoLimit'), GroupManager::MEMBER_PER_GROUP_NO_LIMIT),
$form->createElement('radio', 'max_member_no_limit', null, get_lang('MaximumOfParticipants'), 1, ['id' => 'max_member_selected']),
$form->createElement(
'radio',
'max_member_no_limit',
get_lang('GroupLimit'),
get_lang('NoLimit'),
GroupManager::MEMBER_PER_GROUP_NO_LIMIT
),
$form->createElement(
'radio',
'max_member_no_limit',
null,
get_lang('MaximumOfParticipants'),
1,
['id' => 'max_member_selected']
),
$form->createElement('text', 'max_member', null, ['class' => 'span1', 'id' => 'max_member']),
$form->createElement('static', null, null, ' '.get_lang('GroupPlacesThis')),
];
@ -81,13 +98,26 @@ $form->addElement('html', '<div class="col-md-6">');
// Self registration
$group = [
$form->createElement('checkbox', 'self_registration_allowed', get_lang('GroupSelfRegistration'), get_lang('GroupAllowStudentRegistration'), 1),
$form->createElement('checkbox', 'self_unregistration_allowed', null, get_lang('GroupAllowStudentUnregistration'), 1),
$form->createElement(
'checkbox',
'self_registration_allowed',
get_lang('GroupSelfRegistration'),
get_lang('GroupAllowStudentRegistration'),
1
),
$form->createElement(
'checkbox',
'self_unregistration_allowed',
null,
get_lang('GroupAllowStudentUnregistration'),
1
),
];
$form->addGroup(
$group,
'',
Display::return_icon('user.png', get_lang('GroupSelfRegistration')).'<span>'.get_lang('GroupSelfRegistration').'</span>',
Display::return_icon('user.png', get_lang('GroupSelfRegistration')).
'<span>'.get_lang('GroupSelfRegistration').'</span>',
null,
false
);
@ -217,6 +247,7 @@ $group = [
$form->createElement('radio', 'announcements_state', get_lang('GroupAnnouncements'), get_lang('NotAvailable'), GroupManager::TOOL_NOT_AVAILABLE),
$form->createElement('radio', 'announcements_state', null, get_lang('Public'), GroupManager::TOOL_PUBLIC),
$form->createElement('radio', 'announcements_state', null, get_lang('Private'), GroupManager::TOOL_PRIVATE),
$form->createElement('radio', 'announcements_state', null, get_lang('PrivateBetweenUsers'), GroupManager::TOOL_PRIVATE_BETWEEN_USERS),
];
$form->addGroup(

@ -10,6 +10,7 @@ $action = isset($_REQUEST['a']) ? $_REQUEST['a'] : null;
$isAllowedToEdit = api_is_allowed_to_edit();
$courseInfo = api_get_course_info();
$courseId = api_get_course_int_id();
$groupId = api_get_group_id();
$sessionId = api_get_session_id();
@ -35,12 +36,17 @@ switch ($action) {
}
if ($allowToEdit === false && !empty($groupId)) {
$groupProperties = GroupManager:: get_group_properties($groupId);
$groupProperties = GroupManager::get_group_properties($groupId);
// Check if user is tutor group
$isTutor = GroupManager::is_tutor_of_group(api_get_user_id(), $groupProperties, $courseId);
if ($isTutor) {
$allowToEdit = true;
}
// Last chance ... students can send announcements.
if ($groupProperties['announcements_state'] == GroupManager::TOOL_PRIVATE_BETWEEN_USERS) {
$allowToEdit = true;
}
}
if ($allowToEdit === false) {

@ -127,7 +127,7 @@ class AnnouncementManager
$value = $extra['value'];
if ($value instanceof ExtraFieldValues) {
$field = $value->getField();
if ($field) {
if ($field instanceof ExtraFieldEntity) {
$data['extra_'.$field->getVariable()] = $value->getValue();
}
}
@ -162,7 +162,7 @@ class AnnouncementManager
*/
public static function get_all_annoucement_by_course($course_info, $session_id = 0)
{
$session_id = intval($session_id);
$session_id = (int) $session_id;
$courseId = $course_info['real_id'];
$tbl_announcement = Database::get_course_table(TABLE_ANNOUNCEMENT);
@ -318,13 +318,15 @@ class AnnouncementManager
* @param int $announcementId
* @param int $courseId
* @param int $userId
* @param int $groupId
*
* @return array
*/
public static function getAnnouncementInfoById(
$announcementId,
$courseId,
$userId
$userId,
$groupId = 0
) {
if (api_is_allowed_to_edit(false, true) ||
(api_get_course_setting('allow_user_edit_announcement') && !api_is_anonymous())
@ -339,13 +341,22 @@ class AnnouncementManager
a.cId = :course
ORDER BY a.displayOrder DESC";
} else {
$group_list = GroupManager::get_group_ids($courseId, api_get_user_id());
if (empty($group_list)) {
$group_list[] = 0;
}
$groupId = (int) $groupId;
$groupList[] = $groupId;
if (api_get_user_id() != 0) {
$extraGroupCondition = '';
if (!empty($groupId)) {
$groupProperties = GroupManager::get_group_properties($groupId);
if ($groupProperties['announcements_state'] == GroupManager::TOOL_PRIVATE_BETWEEN_USERS) {
$extraGroupCondition = " AND (
ip.toUser = $userId AND ip.group = $groupId OR
(ip.group IN ('0') OR ip.group IS NULL) OR
(ip.group = $groupId AND (ip.toUser IS NULL OR ip.toUser = 0))
)";
}
}
$dql = "SELECT a, ip
FROM ChamiloCourseBundle:CAnnouncement a
JOIN ChamiloCourseBundle:CItemProperty ip
@ -355,11 +366,12 @@ class AnnouncementManager
ip.tool='announcement' AND
(
ip.toUser = $userId OR
ip.group IN ('0', '".implode("', '", $group_list)."') OR
ip.group IN ('0', '".$groupId."') OR
ip.group IS NULL
) AND
ip.visibility = '1' AND
ip.course = :course
$extraGroupCondition
ORDER BY a.displayOrder DESC";
} else {
$dql = "SELECT a, ip
@ -383,14 +395,14 @@ class AnnouncementManager
]
);
if (empty($result)) {
return [];
if (!empty($result)) {
return [
'announcement' => $result[0],
'item_property' => $result[1],
];
}
return [
'announcement' => $result[0],
'item_property' => $result[1],
];
return [];
}
/**
@ -402,8 +414,10 @@ class AnnouncementManager
*/
public static function displayAnnouncement($id)
{
if ($id != strval(intval($id))) {
return null;
$id = (int) $id;
if (empty($id)) {
return '';
}
global $charset;
@ -412,8 +426,14 @@ class AnnouncementManager
$result = self::getAnnouncementInfoById(
$id,
api_get_course_int_id(),
api_get_user_id()
api_get_user_id(),
api_get_group_id()
);
if (empty($result)) {
return '';
}
/** @var CAnnouncement $announcement */
$announcement = $result['announcement'];
/** @var CItemProperty $itemProperty */
@ -470,7 +490,7 @@ class AnnouncementManager
$html .= "</td></tr>";
$allow = !api_get_configuration_value('hide_announcement_sent_to_users_info');
if (api_is_allowed_to_edit(false, true) && $allow) {
if ($allow && api_is_allowed_to_edit(false, true)) {
$sent_to = self::sent_to('announcement', $id);
$sentToForm = self::sent_to_form($sent_to);
$html .= Display::tag(
@ -505,7 +525,7 @@ class AnnouncementManager
}
$html .= '</td></tr>';
}
$html .= "</table>";
$html .= '</table>';
return $html;
}
@ -1783,7 +1803,7 @@ class AnnouncementManager
if ($user_id) {
if ($allowUserEditSetting && !api_is_anonymous()) {
$cond_user_id = " AND (
ip.lastedit_user_id = '".api_get_user_id()."' OR
ip.lastedit_user_id = '".api_get_user_id()."' OR
((ip.to_user_id='$user_id' OR ip.to_user_id IS NULL) AND
(ip.to_group_id='0' OR ip.to_group_id IS NULL)
)
@ -2021,8 +2041,14 @@ class AnnouncementManager
'id' => $row['id'],
'title' => $title,
'username' => $username_span,
'insert_date' => api_convert_and_format_date($row['insert_date'], DATE_TIME_FORMAT_LONG),
'lastedit_date' => api_convert_and_format_date($row['lastedit_date'], DATE_TIME_FORMAT_LONG),
'insert_date' => api_convert_and_format_date(
$row['insert_date'],
DATE_TIME_FORMAT_LONG
),
'lastedit_date' => api_convert_and_format_date(
$row['lastedit_date'],
DATE_TIME_FORMAT_LONG
),
'actions' => $modify_icons,
];

@ -407,6 +407,7 @@ define('SCORE_CUSTOM', 10); // Good!
define('SCORE_DIV_SIMPLE_WITH_CUSTOM', 11); // X - Good!
define('SCORE_DIV_SIMPLE_WITH_CUSTOM_LETTERS', 12); // X - Good!
define('SCORE_ONLY_SCORE', 13); // X - Good!
define('SCORE_NUMERIC', 14);
define('SCORE_BOTH', 1);
define('SCORE_ONLY_DEFAULT', 2);
@ -948,6 +949,7 @@ function api_get_path($path = '', $configuration = [])
//$paths[$root_web][REL_PATH] = $virtualChamilo[REL_PATH];
//$paths[$root_web][REL_COURSE_PATH] = $virtualChamilo[REL_COURSE_PATH];
}
$isInitialized[$root_web] = true;
}
@ -959,6 +961,7 @@ function api_get_path($path = '', $configuration = [])
}
// Second purification.
// Replacing Windows back slashes.
$path = str_replace('\\', '/', $path);
// Query strings sometimes mighth wrongly appear in non-URLs.
@ -968,6 +971,7 @@ function api_get_path($path = '', $configuration = [])
}
// Detection of the input path type. Conversion to semi-absolute type ( /chamilo/main/inc/.... ).
if (preg_match(VALID_WEB_PATH, $path)) {
// A special case: When a URL points to the document download script directly, without
// mod-rewrite translation, we have to translate it into an "ordinary" web path.
@ -1148,7 +1152,6 @@ function api_valid_email($address)
function api_protect_course_script($print_headers = false, $allow_session_admins = false, $allow_drh = false)
{
$course_info = api_get_course_info();
if (empty($course_info)) {
api_not_allowed($print_headers);
@ -1664,7 +1667,7 @@ function _api_format_user($user, $add_password = false, $loadAvatars = true)
* @param bool $loadAvatars turn off to improve performance and if avatars are not needed
* @param bool $updateCache update apc cache if exists
*
* @return array $user_info user_id, lastname, firstname, username, email, etc
* @return mixed $user_info user_id, lastname, firstname, username, email, etc or false on error
*
* @author Patrick Cool <patrick.cool@UGent.be>
* @author Julio Montoya
@ -4014,13 +4017,13 @@ function convert_sql_date($last_post_datetime)
* the only one that is actually from the session, in case there are results from
* session 0 *AND* session n).
*
* @param array Course properties array (result of api_get_course_info())
* @param string Tool (learnpath, document, etc)
* @param int The item ID in the given tool
* @param int The session ID (optional)
* @param string $tool
* @param array $_course Course properties array (result of api_get_course_info())
* @param string $tool Tool (learnpath, document, etc)
* @param int $id The item ID in the given tool
* @param int $session The session ID (optional)
* @param int $user_id
* @param string $type
* @param string $group_id
*
* @return int -1 on error, 0 if invisible, 1 if visible
*/
@ -4897,8 +4900,12 @@ function api_get_language_id($language)
*/
function api_get_language_info($languageId)
{
if (empty($languageId)) {
return [];
}
$language = Database::getManager()
->find('ChamiloCoreBundle:Language', intval($languageId));
->find('ChamiloCoreBundle:Language', $languageId);
if (!$language) {
return [];

@ -871,4 +871,64 @@ class Certificate extends Model
return Database::store_result($rs, 'ASSOC');
}
/**
* @param int $userId
*/
public static function generateUserSkills($userId)
{
$controller = new IndexManager(get_lang('MyCourses'));
$courseAndSessions = $controller->returnCoursesAndSessions($userId, true, null, true, false);
if (isset($courseAndSessions['courses']) && !empty($courseAndSessions['courses'])) {
foreach ($courseAndSessions['courses'] as $course) {
$cats = Category::load(
null,
null,
$course['code'],
null,
null,
null,
false
);
if (isset($cats[0]) && !empty($cats[0])) {
Category::generateUserCertificate(
$cats[0]->get_id(),
$userId
);
}
}
}
if (isset($courseAndSessions['sessions']) && !empty($courseAndSessions['sessions'])) {
foreach ($courseAndSessions['sessions'] as $sessionCategory) {
if (isset($sessionCategory['sessions'])) {
foreach ($sessionCategory['sessions'] as $sessionData) {
if (!empty($sessionData['courses'])) {
$sessionId = $sessionData['session_id'];
foreach ($sessionData['courses'] as $courseData) {
$cats = Category:: load(
null,
null,
$courseData['course_code'],
null,
null,
$sessionId,
false
);
if (isset($cats[0]) && !empty($cats[0])) {
Category::generateUserCertificate(
$cats[0]->get_id(),
$userId
);
}
}
}
}
}
}
}
}
}

@ -3209,29 +3209,47 @@ class CourseManager
*/
public static function get_details_course_description_html(
$descriptions,
$fieldValues
$charset,
$action_show = true
) {
$data = null;
$info = null;
$data['extrafield'] = $fieldValues;
if (isset($descriptions) && count($descriptions) > 0) {
foreach ($descriptions as $description) {
if ($description->description_type === '1') {
$data['description'] = [
'title' => Security::remove_XSS($description->title),
'content' => Security::remove_XSS($description->content),
];
$data .= '<div class="sectiontitle">';
if (api_is_allowed_to_edit() && $action_show) {
//delete
$data .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete&description_id='.$description->id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities(
get_lang('ConfirmYourChoice'),
ENT_QUOTES,
$charset
)).'\')) return false;">';
$data .= Display::return_icon(
'delete.gif',
get_lang('Delete'),
['style' => 'vertical-align:middle;float:right;']
);
$data .= '</a> ';
//edit
$data .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&description_id='.$description->id.'">';
$data .= Display::return_icon(
'edit.png',
get_lang('Edit'),
['style' => 'vertical-align:middle;float:right; padding-right:4px;'],
ICON_SIZE_SMALL
);
$data .= '</a> ';
}
$data .= $description->title;
$data .= '</div>';
$data .= '<div class="sectioncomment">';
$data .= Security::remove_XSS($description->content);
$data .= '</div>';
}
} else {
$data .= '<em>'.get_lang('ThisCourseDescriptionIsEmpty').'</em>';
}
$template = new Template(null);
$essence = new Essence\Essence();
$template->assign('essence', $essence);
$template->assign('data', $data);
$layout = $template->get_template('auth/modal_description.html.twig');
$info = $template->fetch($layout);
return $info;
return $data;
}
/**

@ -460,7 +460,7 @@ class CourseHome
}
}
if (is_array($lnk)) {
$html .= '<div class="float-right">';
$html .= '<div class="pull-right">';
$html .= '<div class="btn-options">';
$html .= '<div class="btn-group btn-group-sm" role="group">';
foreach ($lnk as &$this_link) {
@ -846,7 +846,7 @@ class CourseHome
$studentview = false;
$tool['original_link'] = $tool['link'];
if ($tool['image'] == 'scormbuilder.gif') {
// check if the published learnpath is visible for student
// Check if the published learnpath is visible for student
$lpId = self::getPublishedLpIdFromLink($tool['link']);
if (api_is_allowed_to_edit(null, true)) {
$studentview = true;

@ -63,9 +63,27 @@ class DateRangePicker extends HTML_QuickForm_text
$start = isset($dates[0]) ? $dates[0] : '';
$end = isset($dates[1]) ? $dates[1] : '';
$pattern = 'yyyy-MM-dd HH:mm';
if ('false' === $this->getAttribute('timePicker') &&
false === strpos($this->getAttribute('format'), 'HH:mm')) {
$pattern = 'yyyy-MM-dd';
}
$formatter = new IntlDateFormatter(
'en',
IntlDateFormatter::NONE,
IntlDateFormatter::NONE,
'UTC',
IntlDateFormatter::GREGORIAN,
$pattern
);
$resultStart = $formatter->format($formatter->parse($start));
$resultEnd = $formatter->format($formatter->parse($end));
return [
'start' => $start,
'end' => $end,
'start' => $resultStart,
'end' => $resultEnd,
];
}
@ -161,7 +179,7 @@ class DateRangePicker extends HTML_QuickForm_text
$timePicker = 'true';
$timePickerValue = Security::remove_XSS($this->getAttribute('timePicker'));
if (!empty($timePickerValue)) {
$timePicker = $timePickerValue;
$timePicker = 'false';
}
// timeFormat: 'hh:mm'

@ -1819,11 +1819,11 @@ class GroupManager
$course_id = empty($course_id) ? api_get_course_int_id() : (int) $course_id;
$group_id = $groupInfo['id'];
$table = Database::get_course_table(TABLE_GROUP_USER);
if (!empty($user_ids)) {
$table = Database::get_course_table(TABLE_GROUP_USER);
foreach ($user_ids as $user_id) {
if (self::canUserSubscribe($user_id, $groupInfo)) {
$user_id = intval($user_id);
$user_id = (int) $user_id;
$sql = "INSERT INTO ".$table." (c_id, user_id, group_id)
VALUES ('$course_id', '".$user_id."', '".$group_id."')";
Database::query($sql);
@ -2142,6 +2142,13 @@ class GroupManager
return true;
}
break;
case self::TOOL_PRIVATE_BETWEEN_USERS:
// Only works for announcements for now
$userIsInGroup = self::is_user_in_group($user_id, $groupInfo);
if ($userIsInGroup && $tool == self::GROUP_TOOL_ANNOUNCEMENT) {
return true;
}
break;
}
return false;
@ -2860,17 +2867,16 @@ class GroupManager
echo '
<ul class="toolbar-groups nav nav-tabs">
<li class="'.$activeSettings.'">
<a href="'.sprintf($url, 'settings.php').'">
<a id="group_settings_tab" href="'.sprintf($url, 'settings.php').'">
'.Display::return_icon('settings.png').' '.get_lang('Settings').'
</a>
</li>
<li class="'.$activeMember.'">
<a href="'.sprintf($url, 'member_settings.php').'">
'.Display::return_icon('user.png').' '.get_lang('GroupMembers').'
</a>
<a id="group_members_tab" href="'.sprintf($url, 'member_settings.php').'">
'.Display::return_icon('user.png').' '.get_lang('GroupMembers').'</a>
</li>
<li class="'.$activeTutor.'">
<a href="'.sprintf($url, 'tutor_settings.php').'">
<a id="group_tutors_tab" href="'.sprintf($url, 'tutor_settings.php').'">
'.Display::return_icon('teacher.png').' '.get_lang('GroupTutors').'
</a>
</li>

@ -1,181 +1,198 @@
.chatboxmain {
position: fixed;
width: auto;
z-index: 9000;
bottom: 0px;
right: 20px;
display: block;
position: fixed;
width: auto;
z-index: 9000;
bottom: 0px;
right: 20px;
display: block;
}
.chatboxheadmain {
color: #ffffff;
background-color: #000;
min-height: 34px;
padding: 0 10px;
color: #ffffff;
background-color: #000;
min-height: 34px;
padding: 0 10px;
}
#chatboxtitlemain {
font-weight: normal;
float: left;
font-size: 12px;
padding-top: 2px;
cursor:pointer;
font-weight: normal;
float: left;
font-size: 12px;
padding-top: 2px;
cursor: pointer;
}
.user_status_main {
width:18px;
display:inline;
float:left;
width: 18px;
display: inline;
float: left;
}
.chatbox {
position: fixed;
position:expression("absolute");
width: 320px;
display:none;
z-index: 9000;
position: fixed;
position: expression("absolute");
width: 320px;
display: none;
z-index: 9000;
}
.chatbox-common {
word-wrap: break-word;
}
.chatboxmessage_me {
background-color: #4080ff;
color: #fff;
width: 80%;
float:right !important;
float: right !important;
border-radius: 12px;
}
.chatboxmessage {
background-color: #ebedf2;
color: #2a2f35;
margin-left:1em;
margin-left: 1em;
width: 80%;
float:left;
float: left;
border-radius: 12px;
}
.chatboxmessagecontent {
}
.chatboxmessage_me .chatboxmessagecontent a {
color: #ffffff;
}
.chatboxcontent {
font-family: arial,sans-serif;
font-size: 13px;
color: #333333;
height:200px;
overflow-y:auto;
overflow-x:auto;
padding:7px;
border-left:1px solid #cccccc;
border-right:1px solid #cccccc;
border-bottom:1px solid #eeeeee;
background-color: #ffffff;
line-height: 1.3em;
font-family: arial, sans-serif;
font-size: 13px;
color: #333333;
max-height: 200px;
overflow-y: auto;
overflow-x: auto;
padding: 7px;
border-left: 1px solid #cccccc;
border-right: 1px solid #cccccc;
border-bottom: 1px solid #eeeeee;
background-color: #ffffff;
line-height: 1.3em;
}
.chatboxcontent .alert {
margin-bottom: 0;
}
.user_status {
width:8px;
display:inline-block;
margin-right: 5px;
width: 8px;
display: inline-block;
margin-right: 5px;
}
.chatimage {
display: inline-block;
margin-right: 5px;
display: inline-block;
margin-right: 5px;
}
.chatboxtitle {
font-weight: normal;
display: inline-block;
font-size: 10px;
width: auto;
cursor:pointer;
overflow: hidden;
padding-left: 2px;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 10px;
font-weight: normal;
display: inline-block;
font-size: 10px;
width: auto;
cursor: pointer;
overflow: hidden;
padding-left: 2px;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 10px;
}
.chatboxhead {
/* background-color: #222; */
padding: 5px;
color: #ffffff;
border-right:1px solid #222;
border-left:1px solid #222;
background-color: #222;
background-repeat: repeat-x;
background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
background-image: -moz-linear-gradient(top, #333333, #222222);
background-image: -ms-linear-gradient(top, #333333, #222222);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
background-image: -webkit-linear-gradient(top, #333333, #222222);
background-image: -o-linear-gradient(top, #333333, #222222);
background-image: linear-gradient(top, #333333, #222222);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
/* background-color: #222; */
padding: 5px;
color: #ffffff;
border-right: 1px solid #222;
border-left: 1px solid #222;
background-color: #222;
background-repeat: repeat-x;
background-image: -khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));
background-image: -moz-linear-gradient(top, #333333, #222222);
background-image: -ms-linear-gradient(top, #333333, #222222);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));
background-image: -webkit-linear-gradient(top, #333333, #222222);
background-image: -o-linear-gradient(top, #333333, #222222);
background-image: linear-gradient(top, #333333, #222222);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
}
.chatboxblink {
background-color: #FF921F;
border-right:1px solid #EF7A00;
border-left:1px solid #EF7A00;
background-color: #FF921F;
border-right: 1px solid #EF7A00;
border-left: 1px solid #EF7A00;
background-repeat: repeat-x;
background-image: -khtml-gradient(linear, left top, left bottom, from(#FF921F), to(#FF921F));
background-image: -moz-linear-gradient(top, #FF921F, #FFAC55);
background-image: -ms-linear-gradient(top, #FF921F, #FF921F);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FF921F), color-stop(100%, #FF921F));
background-image: -webkit-linear-gradient(top, #FF921F, #FF921F);
background-image: -o-linear-gradient(top, #FF921F, #FF921F);
background-image: linear-gradient(top, #FF921F, #FF921F);
background-image: -khtml-gradient(linear, left top, left bottom, from(#FF921F), to(#FF921F));
background-image: -moz-linear-gradient(top, #FF921F, #FFAC55);
background-image: -ms-linear-gradient(top, #FF921F, #FF921F);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FF921F), color-stop(100%, #FF921F));
background-image: -webkit-linear-gradient(top, #FF921F, #FF921F);
background-image: -o-linear-gradient(top, #FF921F, #FF921F);
background-image: linear-gradient(top, #FF921F, #FF921F);
}
.chatboxinput {
padding: 5px;
background-color: #ffffff;
border-left:1px solid #cccccc;
border-right:1px solid #cccccc;
border-bottom:1px solid #cccccc;
padding: 5px;
background-color: #ffffff;
border-left: 1px solid #cccccc;
border-right: 1px solid #cccccc;
border-bottom: 1px solid #cccccc;
}
.chatboxtextarea {
width: 300px;
height:44px;
padding:3px 0pt 3px 3px;
border: 1px solid #eeeeee;
margin: 1px;
overflow:hidden;
width: 300px;
height: 44px;
padding: 3px 0pt 3px 3px;
border: 1px solid #eeeeee;
margin: 1px;
overflow: hidden;
}
.chatboxtextareaselected {
border: 2px solid #f99d39;
margin:0;
border: 2px solid #f99d39;
margin: 0;
}
.chatboxinfo {
margin-left:-1em;
color:#666666;
margin-left: -1em;
color: #666666;
}
.chatboxmessagefrom {
margin-left:-1em;
font-weight: bold;
margin-left: -1em;
font-weight: bold;
}
.chatboxoptions {
float: right;
float: right;
}
.chatboxoptions a {
text-decoration: none;
color: white;
font-weight:bold;
font-family:Verdana,Arial,"Bitstream Vera Sans",sans-serif;
text-decoration: none;
color: white;
font-weight: bold;
font-family: Verdana, Arial, "Bitstream Vera Sans", sans-serif;
}
.chatboxoptions a:hover {
background-color: #aaa;
background-color: #aaa;
}
.chatbox_checks {
float:right;
float: right;
}
.chatbox_checked {
color: #13A7F0;
color: #13A7F0;
}

@ -165,7 +165,6 @@ function startChatSession()
window_user_info.avatar_small
);
}
createChatBubble(my_user_id, item);
}
});
@ -279,7 +278,6 @@ function chatHeartbeat()
newMessagesWin[my_user_id]= {'status':true, 'username':item.username};
var chatBubble = createChatBubble(my_user_id, item);
//$("#chatbox_"+my_user_id+" .chatboxcontent").append(chatBubble);
$("#chatbox_"+my_user_id+" .chatboxcontent").scrollTop(
$("#chatbox_"+my_user_id+" .chatboxcontent")[0].scrollHeight
@ -338,18 +336,22 @@ function createChatBubble(my_user_id, item, appendType = 'append')
var messageObject = $("#chatbox_"+my_user_id+" .chatboxcontent").find('#message_id_' + item.id);
var exists = messageObject.length !== 0;
var messageHeader = '<div id="message_id_'+item.id+'" class="chatbox-common boot-tooltip well '+myDiv+'" title="'+sentDate+'" >';
var messageHeader = '<div id="message_id_'+item.id+'" class="chatbox-common well '+myDiv+'" title="'+sentDate+'" >';
var messageEnd = '</div>';
var message = '';
if (my_user_id == item.from_user_info.id) {
message += '<span class="chatboxmessagefrom">'+item.from_user_info.complete_name+':&nbsp;&nbsp;</span>';
}
message += '<div class="chatboxmessagecontent">'+item.message+'</div>';
message += '<div class="chatbox_checks' + unCheckClass + '">'+check+'</div>';
if (exists) {
messageObject.html(message);
$(messageObject).linkify({
target: "_blank"
});
} else {
message = messageHeader + message + messageEnd;
if (appendType == 'append') {
@ -358,6 +360,9 @@ function createChatBubble(my_user_id, item, appendType = 'append')
$("#chatbox_"+my_user_id+" .chatboxcontent").prepend(message);
}
$("#chatbox_"+my_user_id+" .chatboxcontent").linkify({
target: "_blank"
});
}
return message;
@ -369,9 +374,7 @@ function createChatBubble(my_user_id, item, appendType = 'append')
function closeChat()
{
$.post(
ajax_url + "?action=close",
{
},
ajax_url + "?action=close", {},
function (data) {
// Disconnects from chat
set_user_status(0);
@ -730,7 +733,7 @@ function createChatBox(user_id, chatboxtitle, minimizeChatBox, online, userImage
$("#chatbox_"+user_id).click(function() {
if ($('#chatbox_'+user_id+' .chatboxcontent').css('display') != 'none') {
$("#chatbox_"+user_id+" .chatboxtextarea").focus();
//$("#chatbox_"+user_id+" .chatboxtextarea").focus();
}
});
@ -756,36 +759,21 @@ function getMoreItems(userId, scrollType)
cache: false,
dataType: "json",
success: function(items) {
console.log(items);
items = items.reverse();
$.each(items, function(i, item) {
console.log(i);
if (item) {
if ($("#chatbox_"+userId).css('display') == 'none') {
$("#chatbox_"+userId).css('display','block');
restructureChatBoxes();
}
var chatBubble = createChatBubble(userId, item, 'prepend');
//$("#chatbox_"+userId+" .chatboxcontent").prepend(chatBubble);
if ($('#chatbox_'+userId+' .chatboxcontent').css('display') == 'none') {
$('#chatbox_'+userId+' .chatboxhead').toggleClass('chatboxblink');
}
// When using scroll set the scroll window to the first
var scrollValue = 10;
if (scrollType === 'last') {
// When loading for the first time show the last msg
//scrollValue = $("#chatbox_"+userId+" .chatboxcontent").height();
}
/*$("#chatbox_"+userId+" .chatboxcontent").scrollTop(
scrollValue
);*/
}
});
}
}); //ajax
});
}
/**
@ -847,7 +835,6 @@ function toggleChatBoxGrowth(user_id)
Cookies.set('chatbox_minimized', newCookie);
$('#chatbox_'+user_id+' .chatboxcontent').css('display','block');
$('#chatbox_'+user_id+' .chatboxinput').css('display','block');
//$("#chatbox_"+user_id+" .chatboxcontent").scrollTop($("#chatbox_"+user_id+" .chatboxcontent")[0].scrollHeight);
$('.togglelink').html('<em class="fa fa-toggle-down"></em>');
} else {
// hide box
@ -926,8 +913,7 @@ function checkChatBoxInputKey(event, chatboxtextarea, user_id)
message: message,
id: messageId
};
var bubble = createChatBubble(user_id, item);
//$("#chatbox_" + user_id + " .chatboxcontent").append(bubble);
createChatBubble(user_id, item);
$("#chatbox_" + user_id + " .chatboxcontent").scrollTop(
$("#chatbox_" + user_id + " .chatboxcontent")[0].scrollHeight
);

@ -133,7 +133,9 @@ CKEDITOR.dialog.add('qMarkersrollsDialog', function (editor) {
var label = document.createElement('label');
label.textContent = quiz.title;
label.htmlFor = 'ck-qmr-quiz-' + quiz.id;
label.style.verticalAlign = 'super';
label.style.verticalAlign = 'top';
label.style.whiteSpace = 'normal';
label.style.display = 'inline-block';
var radio = document.createElement('input');
radio.type = 'radio';
@ -141,7 +143,7 @@ CKEDITOR.dialog.add('qMarkersrollsDialog', function (editor) {
radio.id = 'ck-qmr-quiz-' + quiz.id;
radio.value = quiz.id;
var row = document.createElement('div');
var row = document.createElement('li');
row.appendChild(radio);
row.appendChild(label);
@ -187,6 +189,7 @@ CKEDITOR.dialog.add('qMarkersrollsDialog', function (editor) {
}, false);
var divMarker = document.createElement('span');
divMarker.style.whiteSpace = 'normal';
divMarker.innerHTML = ' <strong>' + encodeTime(markerRoll[0]) + '</strong> &mdash; '
+ makerForQuiz.title;
@ -239,8 +242,8 @@ CKEDITOR.dialog.add('qMarkersrollsDialog', function (editor) {
{
type: 'html',
html: lang.embeddableQuizzes + ' '
+ '<div id="ck-qmr-quizzes-container" '
+ 'style="max-height: 110px; overflow: hidden auto;"></div>'
+ '<ul id="ck-qmr-quizzes-container" '
+ 'style="max-height: 110px; overflow: hidden auto; list-style: none;"></ul>'
},
{
type: 'button',

@ -1,306 +1,110 @@
/****
*
* frameReady: Remote function calling for jQuery
*
* Version 1.2.1
*
* Copyright (c) 2007 Daemach (John Wilson) <daemach@gmail.com>, http://ideamill.synaptrixgroup.com
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
* Credit John Resig and his excellent book for the ready function concepts.
*
* Credit to Mike Alsup for the logging code.
* ============================================================================================
* Usage: $.frameReady(function (function),target (string)[,options (map)][,callback (function)]);
*
* Function: (function/required) An anonymous function to be run within the target frame.
*
* Target: (string/required) The target frame. This must be a window object name (in quotes),
* so work from the top down. If you have 3 frames named topFrame, navFrame, mainFrame, and
* an iframe inside of mainframe named iFrame, use "top.topFrame", "top.navFrame",
* "top.mainFrame", "top.mainFrame.iFrame" respectively.
*
* Options: (object/optional) Map of options in object literal form. Options include:
*
* remote: (boolean/ default true) Run the function in the context of the target frame.
* If true, jQuery will be loaded in the target frame automatically and you can run
* jQuery selectors in the target frame as if they were local. ie: $("p") instead of
* $("p",top.mainFrame.document). If false, jQuery will not be loaded automatically
* and you must use a context in jquery selectors.
*
* data: (object) An object to be passed as-is to the target frame. This is where you pass
* variable data, rather than in a closure.
*
* load: (object or array of objects) jquery is loaded by default. You can pass a single object to
* frameReady, or an array of objects that will be loaded and tested in order. 2 types
* of files can be loaded. Scripts and stylesheets:
*
* scripts: {type:"script", src:"/js/myscript.js", id:"_ms", test:"afunction"}
* stylesheets: {type:"stylesheet", src:"/css/mycss.css", id:"_ss"}
*
* type: (string/required) "script" for script files, "stylesheet" for stylesheets.
* src: (string/required) The source of the file, ie: /js/myscript.js.
* id: (string/optional) An id for the id attribute. If one isn't provided it
* will be generated.
* test: (sting/optional) The name of a function that should exist once the script
* is loaded properly. Until this function becomes available, the script will
* be considered not ready and no other files will be loaded. If a test is not
* provided, the next file will be loaded immediately. Tests are not useful
* with stylesheets.
*
* One gotcha: You must have something other than space characters within the body tags of
* target frame documents for frameReady to work properly. A single character is enough.
* The reason for this is a workaround for an iFrame bug in Firefox, of all things.
* ==============================================================================================
*
* Example:
*
* $.frameReady(function(){
* $("<div>I am a div element</div>").prependTo("body");
* }, "top.mainFrame",
* { load: [
* {type:"script",id:"_fr",src:"/js/jquery.frameReady.js",test: "$.frameReady"},
* {type:"stylesheet",id:"_ss",src:"frameReady.css"}
* ] }
* );
*
*
* Release Notes:
*
* 1.2.0 - Added provision for a local callback function;
* Added functionality to reset frame information if frame unloads for any reason;
*
* 1.1.0 - Added the ability to load scripts and stylesheets inside the target frame before
* processing function stack;
*
****/
if (typeof $daemach == "undefined") {
$daemach = {};
$daemach.debug = false; // set this to true to enable logging
$daemach.log = function() {
if (!top.window.console || !top.window.console.log || !$daemach.debug) {
return;
} else {
top.window.console.log([].join.call(arguments,''));
};
};
$daemach.time = function() {
if (!top.window.console || !top.window.console.time || !$daemach.debug) {
return;
} else {
top.window.console.time([].join.call(arguments,''));
};
};
$daemach.timeEnd = function() {
if (!top.window.console || !top.window.console.timeEnd || !$daemach.debug) {
return;
} else {
top.window.console.timeEnd([].join.call(arguments,''));
};
};
};
if (typeof $daemach["frameReady"] == "undefined") {
$daemach["frameReady"] = {};
};
jQuery.frameReady = function(f,t,r,j) {
/************************************************************
You must specify the path to your jquery.js file below!
*************************************************************/
//var jQueryPath = "/main/inc/lib/javascript/jquery.js";
var jQueryPath = jQueryFrameReadyConfigPath; // Define this configuration parameter before loading this script.
var u = "undefined";
var $fr = $daemach["frameReady"];
var fn = t.split(".").join("_");
// create a branch
if (typeof $fr[fn] == u) {
$fr[fn] = {};
$fr[fn]["settings"] = {
remote: true,
jquery: true,
load: [ {type:"script",id:"_jq", src:jQueryPath, test:"jQuery"} ],
bLoaded: false,
loadInit: [],
data: {},
callback: false
};
$fr[fn]["target"] = t;
};
var fr = $fr[fn];
var frs = fr["settings"];
if (fr.done) {
$daemach.log(fr.target + " is ready. Running functions now.");
return (frs.remote) ? eval(fr.target).eval("(" + f.toString() + ")()") : f();
};
// process arguments
for (var a=2;a<arguments.length;a++){
var arg = arguments[a];
if ($.isFunction(arg)){
frs.callback = arg;
} else if (typeof arg == "object") {
if (typeof arg.remote !== u) {
frs.remote = arg.remote;
};
if (typeof arg.jquery !== u) {
frs.jquery = arg.jquery;
};
if (typeof arg.data !== u) {
frs.data = arg.data;
};
// if we're not running functions in the remote frame itself, no need for jQuery
if (!frs.remote || !frs.jquery) {
frs.load.pop();
};
if (typeof arg.load !== u) {
var bl = true;
if (arg.load.constructor == Array && arg.load.length){
for (var i=0;i<arg.load.length;i++){
bl = true;
for (var h=0;h<frs.load.length;h++){
if (frs.load[h].src == arg.load[i].src) { bl=false; };
};
if (bl) { frs.load.push(arg.load[i]); };
};
} else if (typeof arg.load == "object") {
for (var h=0;h<frs.load.length;h++){
if (frs.load[h].src == arg.load.src) { bl=false; };
};
if (bl) { frs.load.push(arg.load); };
};
};
};
};
if (fr.timer) {
fr.ready.push(f);
} else {
fr.ready=[f];
if (typeof addEvent !== "undefined"){ addEvent(window,"load",function(){ jQuery.isFrameReady(fn); }); };
fr.timer = setInterval(function(){ jQuery.isFrameReady(fn); },13);
};
};
jQuery.isFrameReady = function(fn){
var u = "undefined";
var $d = $daemach;
var fr = $d["frameReady"][fn];
var frs = fr["settings"];
if (fr.done) { return false; };
var fx = eval(fr.target);
$d.log(fn, ": New Pass. Checking target");
// make sure we have a target
if (typeof fx !== "undefined") {
$d.log(fn, ": Found target. Checking DOM");
try {
var fd = fx.document;
} catch (ex) { }
// make sure we have a DOM
if (fd && fd.getElementsByTagName && fd.getElementById && fd.body && fd.body.innerHTML.length) {
$d.log(fn, ": Found DOM");
if (frs.load.length && !frs.bLoaded){
for (var i=0;i<frs.load.length;i++){
var s = frs.load[i];
var _test;
try { _test = eval('typeof fx.'+s.test+ ' !== "undefined"'); }
catch(ex){ _test = false;}
finally { $d.log(fn, ": Running test for script ",i,". ", (_test || !s.test) ? "Passed.":"Failed."); };
if ((_test || !s.test) && frs.loadInit[i]) {
frs.bLoaded = (typeof s.test == u) ? true : _test;
continue;
} else {
frs.bLoaded = false;
if (typeof frs.loadInit[i] == u){
var id = s.id || "frs_"+i;
switch (s.type) {
case "script" :
$d.log(fn, ": Loading script "+ i + " (" + s.src + ")");
var ele=fd.createElement('script');
ele.setAttribute('id', id);
ele.setAttribute('src', s.src);
if (fd.getElementsByTagName("body") && fd.getElementsByTagName("body")[0]) {
fd.getElementsByTagName("body")[0].appendChild(ele);
}
frs.loadInit[i] = true;
break;
case "stylesheet" :
$d.log(fn, ": Loading stylesheet "+ i + " (" + s.src + ")");
var ele=fd.createElement('link');
ele.setAttribute('href', s.src);
ele.setAttribute('rel', "stylesheet");
ele.setAttribute('type', "text/css");
fd.getElementsByTagName("body")[0].appendChild(ele);
frs.loadInit[i] = true;
break;
default :
$d.log(fn, ": Script "+i+" has a bad or missing type attribute..." );
};
};
break;
};
};
} else {
clearInterval(fr.timer);
fr.timer = null;
for (i in frs.data){
if (!fx.frData){
fx.frData={};
}
fx.frData[i] = frs.data[i];
};
fr.ready.push(function(){ window.frameReadyUnload = function(root, fn){ $(window).bind("unload",function(){ root.jQuery.frameReady.unload(fn); }); } });
$d.log(fn, ": Processing function stack:");
for (var i=0; i<fr.ready.length;i++){
(frs.remote) ? fx.eval("(" + fr.ready[i].toString() + ")()") : fr.ready[i]();
};
fx.frameReadyUnload(window,fn);
$d.log(fn, ": Function stack processing complete.");
// we're done here. let's have a beer.
fr.ready = null;
fr.done=true;
if (frs.callback){
$d.log(fn, ": Found a callback. Executing...");
frs.callback();
};
};
};
};
$d.log(fn, ":");
};
jQuery.frameReady.unload = function(fn){
$daemach.log("Frame " + fn + " is unloading. Resetting state.");
$daemach["frameReady"][fn].done = false;
$daemach["frameReady"][fn]["settings"].bLoaded = false;
$daemach["frameReady"][fn]["settings"].loadInit = [];
};
/**
* @param {function} callback
* @param {string} target
* @param {Array} resources
* @constructor
*/
$.frameReady = function (callback, targetSelector, resources) {
/**
* @type {window}
*/
var targetWindow = document.querySelector(targetSelector);
/**
* @type {Document}
*/
var targetDocument = null;
var scripts = resources.filter(function (resource) {
return resource.type === 'script';
});
var stylesheets = resources.filter(function (resource) {
return resource.type === 'stylesheet';
});
var scriptsCount = (function () {
var count = 0;
/**
* @param {Object} parentScript
*/
function countScripts(parentScript) {
count++;
if (!parentScript.hasOwnProperty('deps')) {
return;
}
parentScript.deps.forEach(countScripts);
}
scripts.forEach(countScripts);
return count;
})();
var scripsLoadedCount = 0;
targetWindow.onload = function () {
scripsLoadedCount = 0;
targetDocument = targetWindow.contentDocument;
scripts.forEach(function (script) {
createScript(script);
});
stylesheets.forEach(function (stylesheet) {
createStylesheet(stylesheet);
});
};
/**
* @param {Object} script
*/
function createScript(script) {
/**
* @type {HTMLScriptElement}
*/
var elParent = targetWindow.contentDocument.createElement('script');
elParent.async = false;
elParent.onload = function () {
scripsLoadedCount++;
if (!script.hasOwnProperty('deps')) {
tryExecuteCallback();
return;
}
script.deps.forEach(function (scriptB) {
createScript(scriptB);
});
};
elParent.setAttribute('src', script.src);
targetDocument.body.appendChild(elParent);
}
/**
* @param {Object} stylesheet
*/
function createStylesheet(stylesheet) {
/**
* @type {HTMLLinkElement}
*/
var el = targetWindow.contentDocument.createElement('link');
el.setAttribute('href', stylesheet.src);
el.setAttribute('rel', "stylesheet");
el.setAttribute('type', "text/css");
if (targetDocument.head) {
targetDocument.head.appendChild(el);
}
}
function tryExecuteCallback() {
if (scripsLoadedCount < scriptsCount) {
return;
}
targetWindow.contentWindow.eval('(' + callback.toString() + ')();');
}
};

File diff suppressed because it is too large Load Diff

@ -0,0 +1,28 @@
/*
OverlappingMarkerSpiderfier
https://github.com/jawj/OverlappingMarkerSpiderfier
Copyright (c) 2011 - 2017 George MacKerron
Released under the MIT licence: http://opensource.org/licenses/mit-license
Note: The Google Maps API v3 must be included *before* this code
*/
(function(){var m,t,w,y,u,z={}.hasOwnProperty,A=[].slice;this.OverlappingMarkerSpiderfier=function(){function r(a,d){var b,f,e;this.map=a;null==d&&(d={});null==this.constructor.N&&(this.constructor.N=!0,h=google.maps,l=h.event,p=h.MapTypeId,c.keepSpiderfied=!1,c.ignoreMapClick=!1,c.markersWontHide=!1,c.markersWontMove=!1,c.basicFormatEvents=!1,c.nearbyDistance=20,c.circleSpiralSwitchover=9,c.circleFootSeparation=23,c.circleStartAngle=x/12,c.spiralFootSeparation=26,c.spiralLengthStart=11,c.spiralLengthFactor=
4,c.spiderfiedZIndex=h.Marker.MAX_ZINDEX+2E4,c.highlightedLegZIndex=h.Marker.MAX_ZINDEX+1E4,c.usualLegZIndex=h.Marker.MAX_ZINDEX+1,c.legWeight=1.5,c.legColors={usual:{},highlighted:{}},e=c.legColors.usual,f=c.legColors.highlighted,e[p.HYBRID]=e[p.SATELLITE]="#fff",f[p.HYBRID]=f[p.SATELLITE]="#f00",e[p.TERRAIN]=e[p.ROADMAP]="#444",f[p.TERRAIN]=f[p.ROADMAP]="#f00",this.constructor.j=function(a){return this.setMap(a)},this.constructor.j.prototype=new h.OverlayView,this.constructor.j.prototype.draw=function(){});
for(b in d)z.call(d,b)&&(f=d[b],this[b]=f);this.g=new this.constructor.j(this.map);this.C();this.c={};this.B=this.l=null;this.addListener("click",function(a,b){return l.trigger(a,"spider_click",b)});this.addListener("format",function(a,b){return l.trigger(a,"spider_format",b)});this.ignoreMapClick||l.addListener(this.map,"click",function(a){return function(){return a.unspiderfy()}}(this));l.addListener(this.map,"maptypeid_changed",function(a){return function(){return a.unspiderfy()}}(this));l.addListener(this.map,
"zoom_changed",function(a){return function(){a.unspiderfy();if(!a.basicFormatEvents)return a.h()}}(this))}var l,h,m,v,p,c,t,x,u;c=r.prototype;t=[r,c];m=0;for(v=t.length;m<v;m++)u=t[m],u.VERSION="1.0.3";x=2*Math.PI;h=l=p=null;r.markerStatus={SPIDERFIED:"SPIDERFIED",SPIDERFIABLE:"SPIDERFIABLE",UNSPIDERFIABLE:"UNSPIDERFIABLE",UNSPIDERFIED:"UNSPIDERFIED"};c.C=function(){this.a=[];this.s=[]};c.addMarker=function(a,d){a.setMap(this.map);return this.trackMarker(a,d)};c.trackMarker=function(a,d){var b;if(null!=
a._oms)return this;a._oms=!0;b=[l.addListener(a,"click",function(b){return function(d){return b.V(a,d)}}(this))];this.markersWontHide||b.push(l.addListener(a,"visible_changed",function(b){return function(){return b.D(a,!1)}}(this)));this.markersWontMove||b.push(l.addListener(a,"position_changed",function(b){return function(){return b.D(a,!0)}}(this)));null!=d&&b.push(l.addListener(a,"spider_click",d));this.s.push(b);this.a.push(a);this.basicFormatEvents?this.trigger("format",a,this.constructor.markerStatus.UNSPIDERFIED):
(this.trigger("format",a,this.constructor.markerStatus.UNSPIDERFIABLE),this.h());return this};c.D=function(a,d){if(!this.J&&!this.K)return null==a._omsData||!d&&a.getVisible()||this.unspiderfy(d?a:null),this.h()};c.getMarkers=function(){return this.a.slice(0)};c.removeMarker=function(a){this.forgetMarker(a);return a.setMap(null)};c.forgetMarker=function(a){var d,b,f,e,g;null!=a._omsData&&this.unspiderfy();d=this.A(this.a,a);if(0>d)return this;g=this.s.splice(d,1)[0];b=0;for(f=g.length;b<f;b++)e=g[b],
l.removeListener(e);delete a._oms;this.a.splice(d,1);this.h();return this};c.removeAllMarkers=c.clearMarkers=function(){var a,d,b,f;f=this.getMarkers();this.forgetAllMarkers();a=0;for(d=f.length;a<d;a++)b=f[a],b.setMap(null);return this};c.forgetAllMarkers=function(){var a,d,b,f,e,g,c,q;this.unspiderfy();q=this.a;a=d=0;for(b=q.length;d<b;a=++d){g=q[a];e=this.s[a];c=0;for(a=e.length;c<a;c++)f=e[c],l.removeListener(f);delete g._oms}this.C();return this};c.addListener=function(a,d){var b;(null!=(b=this.c)[a]?
b[a]:b[a]=[]).push(d);return this};c.removeListener=function(a,d){var b;b=this.A(this.c[a],d);0>b||this.c[a].splice(b,1);return this};c.clearListeners=function(a){this.c[a]=[];return this};c.trigger=function(){var a,d,b,f,e,g;d=arguments[0];a=2<=arguments.length?A.call(arguments,1):[];d=null!=(b=this.c[d])?b:[];g=[];f=0;for(e=d.length;f<e;f++)b=d[f],g.push(b.apply(null,a));return g};c.L=function(a,d){var b,f,e,g,c;g=this.circleFootSeparation*(2+a)/x;f=x/a;c=[];for(b=e=0;0<=a?e<a:e>a;b=0<=a?++e:--e)b=
this.circleStartAngle+b*f,c.push(new h.Point(d.x+g*Math.cos(b),d.y+g*Math.sin(b)));return c};c.M=function(a,d){var b,f,e,c,k;c=this.spiralLengthStart;b=0;k=[];for(f=e=0;0<=a?e<a:e>a;f=0<=a?++e:--e)b+=this.spiralFootSeparation/c+5E-4*f,f=new h.Point(d.x+c*Math.cos(b),d.y+c*Math.sin(b)),c+=x*this.spiralLengthFactor/b,k.push(f);return k};c.V=function(a,d){var b,f,e,c,k,q,n,l,h;(q=null!=a._omsData)&&this.keepSpiderfied||this.unspiderfy();if(q||this.map.getStreetView().getVisible()||"GoogleEarthAPI"===
this.map.getMapTypeId())return this.trigger("click",a,d);q=[];n=[];b=this.nearbyDistance;l=b*b;k=this.f(a.position);h=this.a;b=0;for(f=h.length;b<f;b++)e=h[b],null!=e.map&&e.getVisible()&&(c=this.f(e.position),this.i(c,k)<l?q.push({R:e,G:c}):n.push(e));return 1===q.length?this.trigger("click",a,d):this.W(q,n)};c.markersNearMarker=function(a,d){var b,f,e,c,k,q,n,l,h,m;null==d&&(d=!1);if(null==this.g.getProjection())throw"Must wait for 'idle' event on map before calling markersNearMarker";b=this.nearbyDistance;
n=b*b;k=this.f(a.position);q=[];l=this.a;b=0;for(f=l.length;b<f&&!(e=l[b],e!==a&&null!=e.map&&e.getVisible()&&(c=this.f(null!=(h=null!=(m=e._omsData)?m.v:void 0)?h:e.position),this.i(c,k)<n&&(q.push(e),d)));b++);return q};c.F=function(){var a,d,b,f,e,c,k,l,n,h,m;if(null==this.g.getProjection())throw"Must wait for 'idle' event on map before calling markersNearAnyOtherMarker";n=this.nearbyDistance;n*=n;var p;e=this.a;p=[];h=0;for(d=e.length;h<d;h++)f=e[h],p.push({H:this.f(null!=(a=null!=(b=f._omsData)?
b.v:void 0)?a:f.position),b:!1});h=this.a;a=b=0;for(f=h.length;b<f;a=++b)if(d=h[a],null!=d.getMap()&&d.getVisible()&&(c=p[a],!c.b))for(m=this.a,d=l=0,e=m.length;l<e;d=++l)if(k=m[d],d!==a&&null!=k.getMap()&&k.getVisible()&&(k=p[d],(!(d<a)||k.b)&&this.i(c.H,k.H)<n)){c.b=k.b=!0;break}return p};c.markersNearAnyOtherMarker=function(){var a,d,b,c,e,g,k;e=this.F();g=this.a;k=[];a=d=0;for(b=g.length;d<b;a=++d)c=g[a],e[a].b&&k.push(c);return k};c.setImmediate=function(a){return window.setTimeout(a,0)};c.h=
function(){if(!this.basicFormatEvents&&null==this.l)return this.l=this.setImmediate(function(a){return function(){a.l=null;return null!=a.g.getProjection()?a.w():null!=a.B?void 0:a.B=l.addListenerOnce(a.map,"idle",function(){return a.w()})}}(this))};c.w=function(){var a,d,b,c,e,g,k;if(this.basicFormatEvents){e=[];d=0;for(b=markers.length;d<b;d++)c=markers[d],a=null!=c._omsData?"SPIDERFIED":"UNSPIDERFIED",e.push(this.trigger("format",c,this.constructor.markerStatus[a]));return e}e=this.F();g=this.a;
k=[];a=b=0;for(d=g.length;b<d;a=++b)c=g[a],a=null!=c._omsData?"SPIDERFIED":e[a].b?"SPIDERFIABLE":"UNSPIDERFIABLE",k.push(this.trigger("format",c,this.constructor.markerStatus[a]));return k};c.P=function(a){return{m:function(d){return function(){return a._omsData.o.setOptions({strokeColor:d.legColors.highlighted[d.map.mapTypeId],zIndex:d.highlightedLegZIndex})}}(this),u:function(d){return function(){return a._omsData.o.setOptions({strokeColor:d.legColors.usual[d.map.mapTypeId],zIndex:d.usualLegZIndex})}}(this)}};
c.W=function(a,d){var b,c,e,g,k,q,n,m,p,r;this.J=!0;r=a.length;b=this.T(function(){var b,d,c;c=[];b=0;for(d=a.length;b<d;b++)m=a[b],c.push(m.G);return c}());g=r>=this.circleSpiralSwitchover?this.M(r,b).reverse():this.L(r,b);b=function(){var b,d,f;f=[];b=0;for(d=g.length;b<d;b++)e=g[b],c=this.U(e),p=this.S(a,function(a){return function(b){return a.i(b.G,e)}}(this)),n=p.R,q=new h.Polyline({map:this.map,path:[n.position,c],strokeColor:this.legColors.usual[this.map.mapTypeId],strokeWeight:this.legWeight,
zIndex:this.usualLegZIndex}),n._omsData={v:n.getPosition(),X:n.getZIndex(),o:q},this.legColors.highlighted[this.map.mapTypeId]!==this.legColors.usual[this.map.mapTypeId]&&(k=this.P(n),n._omsData.O={m:l.addListener(n,"mouseover",k.m),u:l.addListener(n,"mouseout",k.u)}),this.trigger("format",n,this.constructor.markerStatus.SPIDERFIED),n.setPosition(c),n.setZIndex(Math.round(this.spiderfiedZIndex+e.y)),f.push(n);return f}.call(this);delete this.J;this.I=!0;return this.trigger("spiderfy",b,d)};c.unspiderfy=
function(a){var d,b,c,e,g,k,h;null==a&&(a=null);if(null==this.I)return this;this.K=!0;h=[];g=[];k=this.a;d=0;for(b=k.length;d<b;d++)e=k[d],null!=e._omsData?(e._omsData.o.setMap(null),e!==a&&e.setPosition(e._omsData.v),e.setZIndex(e._omsData.X),c=e._omsData.O,null!=c&&(l.removeListener(c.m),l.removeListener(c.u)),delete e._omsData,e!==a&&(c=this.basicFormatEvents?"UNSPIDERFIED":"SPIDERFIABLE",this.trigger("format",e,this.constructor.markerStatus[c])),h.push(e)):g.push(e);delete this.K;delete this.I;
this.trigger("unspiderfy",h,g);return this};c.i=function(a,d){var b,c;b=a.x-d.x;c=a.y-d.y;return b*b+c*c};c.T=function(a){var c,b,f,e,g;c=e=g=0;for(b=a.length;c<b;c++)f=a[c],e+=f.x,g+=f.y;a=a.length;return new h.Point(e/a,g/a)};c.f=function(a){return this.g.getProjection().fromLatLngToDivPixel(a)};c.U=function(a){return this.g.getProjection().fromDivPixelToLatLng(a)};c.S=function(a,c){var b,d,e,g,k,h;e=k=0;for(h=a.length;k<h;e=++k)if(g=a[e],g=c(g),"undefined"===typeof b||null===b||g<d)d=g,b=e;return a.splice(b,
1)[0]};c.A=function(a,c){var b,d,e,g;if(null!=a.indexOf)return a.indexOf(c);b=d=0;for(e=a.length;d<e;b=++d)if(g=a[b],g===c)return b;return-1};return r}();t=/(\?.*(&|&amp;)|\?)spiderfier_callback=(\w+)/;m=document.currentScript;null==m&&(m=function(){var m,l,h,w,v;h=document.getElementsByTagName("script");v=[];m=0;for(l=h.length;m<l;m++)u=h[m],null!=(w=u.getAttribute("src"))&&w.match(t)&&v.push(u);return v}()[0]);if(null!=m&&(m=null!=(w=m.getAttribute("src"))?null!=(y=w.match(t))?y[3]:void 0:void 0)&&
"function"===typeof window[m])window[m]();"function"===typeof window.spiderfier_callback&&window.spiderfier_callback()}).call(this);
/* Thu 11 May 2017 08:40:57 BST */

@ -46,6 +46,7 @@ class PDF
$params['right'] = isset($params['right']) ? $params['right'] : 15;
$params['top'] = isset($params['top']) ? $params['top'] : 30;
$params['bottom'] = isset($params['bottom']) ? $params['bottom'] : 30;
$params['margin_footer'] = isset($params['margin_footer']) ? $params['margin_footer'] : 8;
$this->params['filename'] = isset($params['filename']) ? $params['filename'] : api_get_local_time();
$this->params['pdf_title'] = isset($params['pdf_title']) ? $params['pdf_title'] : '';
@ -204,6 +205,7 @@ class PDF
* @param bool $print_title add title
* @param bool $complete_style show header and footer if true
* @param bool $addStyle
* @param string $mainTitle
*
* @return false|null
*/
@ -213,7 +215,8 @@ class PDF
$courseCode = null,
$printTitle = false,
$complete_style = true,
$addStyle = true
$addStyle = true,
$mainTitle = ''
) {
if (empty($htmlFileArray)) {
return false;
@ -248,7 +251,6 @@ class PDF
if ($counter == count($htmlFileArray)) {
$pageBreak = '';
}
$counter++;
//if the array provided contained subarrays with 'title' entry,
// then print the title in the PDF
@ -260,14 +262,27 @@ class PDF
$htmlTitle = basename($file);
}
$counter++;
if (empty($file) && !empty($htmlTitle)) {
//this is a chapter, print title & skip the rest
// this is a chapter, print title & skip the rest
if ($counter === 2 && !empty($mainTitle)) {
$this->pdf->WriteHTML(
'<html><body><h2 style="text-align: center">'.$mainTitle.'</h2></body></html>'
);
}
if ($printTitle) {
$this->pdf->WriteHTML(
'<html><body><h3>'.$htmlTitle.'</h3></body></html>'.$pageBreak
'<html><body><h3>'.$html_title.'</h3></body></html>'.$page_break
);
}
continue;
} else {
if ($counter === 2 && !empty($mainTitle)) {
$this->pdf->WriteHTML(
'<html><body><h2 style="text-align: center">'.$mainTitle.'</h2></body></html>'
);
}
}
if (!file_exists($file)) {

@ -29,7 +29,7 @@
* @global array $GLOBALS['_HTML_QuickForm_registered_rules']
*/
/**#@+
/**
* Error codes for HTML_QuickForm
*
* Codes are mapped to textual messages by errorMessage() method, if you add a
@ -62,7 +62,6 @@ define('QUICKFORM_INVALID_DATASOURCE', -9);
class HTML_QuickForm extends HTML_Common
{
const MAX_ELEMENT_ARGUMENT = 10;
private $dateTimePickerLibraryAdded;
/**
@ -267,15 +266,6 @@ class HTML_QuickForm extends HTML_Common
$this->_maxFileSize = $matches['1'];
}
}
// $course_id = api_get_course_int_id();
// //If I'm in a course replace the default max filesize with the course limits
// if (!empty($course_id)) {
// $free_course_quota = DocumentManager::get_course_quota() - DocumentManager::documents_total_space();
// if (empty($this->_maxFileSize) || $free_course_quota <= $this->_maxFileSize) {
// $this->_maxFileSize = intval($free_course_quota);
// }
// }
}
/**
@ -300,7 +290,7 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @return void
*/
function registerElementType($typeName, $include, $className)
public function registerElementType($typeName, $include, $className)
{
$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][strtolower($typeName)] = array($include, $className);
}
@ -454,11 +444,12 @@ class HTML_QuickForm extends HTML_Common
public function &createElement($elementType)
{
$args = func_get_args();
$element = HTML_QuickForm::_loadElement(
$element = $this->_loadElement(
'createElement',
$elementType,
array_slice($args, 1)
);
return $element;
}
@ -667,7 +658,7 @@ class HTML_QuickForm extends HTML_Common
* @param string $name (optional)group name
* @param string $groupLabel (optional)group label
* @param string $separator (optional)string to separate elements
* @param string $appendName (optional)specify whether the group name should be
* @param bool $appendName (optional)specify whether the group name should be
* used in the form element name ex: group[element]
* @return HTML_QuickForm_group reference to a newly added group
* @since 2.8
@ -749,7 +740,7 @@ class HTML_QuickForm extends HTML_Common
* @return mixed element value
* @throws HTML_QuickForm_Error
*/
function &getElementValue($element)
public function &getElementValue($element)
{
if (!isset($this->_elementIndex[$element])) {
throw new \Exception("Element '$element' does not exist in HTML_QuickForm::getElementValue()");
@ -860,7 +851,7 @@ class HTML_QuickForm extends HTML_Common
* @param string The key from the $_FILES array that should be appended
* @return array
*/
function _reindexFiles($value, $key)
public function _reindexFiles($value, $key)
{
if (!is_array($value)) {
return array($key => $value);
@ -881,15 +872,12 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @return string error message corresponding to checked element
*/
function getElementError($element)
public function getElementError($element)
{
if (isset($this->_errors[$element])) {
return $this->_errors[$element];
}
} // end func getElementError
// }}}
// {{{ setElementError()
}
/**
* Set error message for a form element
@ -900,17 +888,14 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @return void
*/
function setElementError($element, $message = null)
public function setElementError($element, $message = null)
{
if (!empty($message)) {
$this->_errors[$element] = $message;
} else {
unset($this->_errors[$element]);
}
} // end func setElementError
// }}}
// {{{ getElementType()
}
/**
* Returns the type of the given element
@ -920,16 +905,13 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @return string Type of the element, false if the element is not found
*/
function getElementType($element)
public function getElementType($element)
{
if (isset($this->_elementIndex[$element])) {
return $this->_elements[$this->_elementIndex[$element]]->getType();
}
return false;
} // end func getElementType
// }}}
// {{{ updateElementAttr()
}
/**
* Updates Attributes for one or more elements
@ -940,7 +922,7 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @return void
*/
function updateElementAttr($elements, $attrs)
public function updateElementAttr($elements, $attrs)
{
if (is_string($elements)) {
$elements = split('[ ]?,[ ]?', $elements);
@ -973,7 +955,7 @@ class HTML_QuickForm extends HTML_Common
* @return HTML_QuickForm_element a reference to the removed element
* @throws HTML_QuickForm_Error
*/
function &removeElement($elementName, $removeRules = true)
public function &removeElement($elementName, $removeRules = true)
{
if (!isset($this->_elementIndex[$elementName])) {
throw new \Exception("Element '$elementName' does not exist in HTML_QuickForm::removeElement()");
@ -1089,7 +1071,7 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @throws HTML_QuickForm_Error
*/
function addGroupRule($group, $arg1, $type='', $format=null, $howmany=0, $validation = 'server', $reset = false)
public function addGroupRule($group, $arg1, $type='', $format=null, $howmany=0, $validation = 'server', $reset = false)
{
if (!$this->elementExists($group)) {
throw new \Exception("Group '$group' does not exist in HTML_QuickForm::addGroupRule()");
@ -1166,10 +1148,7 @@ class HTML_QuickForm extends HTML_Common
$this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
}
}
} // end func addGroupRule
// }}}
// {{{ addFormRule()
}
/**
* Adds a global validation rule
@ -1191,9 +1170,6 @@ class HTML_QuickForm extends HTML_Common
$this->_formRules[] = $rule;
}
// }}}
// {{{ applyFilter()
/**
* Applies a data filter for the given field(s)
*
@ -1203,7 +1179,7 @@ class HTML_QuickForm extends HTML_Common
* @access public
* @throws HTML_QuickForm_Error
*/
function applyFilter($element, $filter)
public function applyFilter($element, $filter)
{
if (!is_callable($filter)) {
throw new \Exception("Callback function does not exist in QuickForm::applyFilter()");
@ -1229,10 +1205,7 @@ class HTML_QuickForm extends HTML_Common
}
}
}
} // end func applyFilter
// }}}
// {{{ _recursiveFilter()
}
/**
* Recursively apply a filter function
@ -1243,7 +1216,7 @@ class HTML_QuickForm extends HTML_Common
* @access private
* @return cleaned values
*/
function _recursiveFilter($filter, $value)
public function _recursiveFilter($filter, $value)
{
if (is_array($value)) {
$cleanValues = array();
@ -1254,10 +1227,7 @@ class HTML_QuickForm extends HTML_Common
} else {
return call_user_func($filter, $value);
}
} // end func _recursiveFilter
// }}}
// {{{ arrayMerge()
}
/**
* Merges two arrays
@ -1288,10 +1258,7 @@ class HTML_QuickForm extends HTML_Common
}
}
return $a;
} // end func arrayMerge
// }}}
// {{{ isTypeRegistered()
}
/**
* Returns whether or not the form element type is supported
@ -1316,10 +1283,7 @@ class HTML_QuickForm extends HTML_Common
function getRegisteredTypes()
{
return array_keys($GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']);
} // end func getRegisteredTypes
// }}}
// {{{ isRuleRegistered()
}
/**
* Returns whether or not the given rule is supported
@ -1345,10 +1309,7 @@ class HTML_QuickForm extends HTML_Common
function getRegisteredRules()
{
return array_keys($GLOBALS['_HTML_QuickForm_registered_rules']);
} // end func getRegisteredRules
// }}}
// {{{ isElementRequired()
}
/**
* Returns whether or not the form element is required
@ -1361,10 +1322,7 @@ class HTML_QuickForm extends HTML_Common
function isElementRequired($element)
{
return in_array($element, $this->_required, true);
} // end func isElementRequired
// }}}
// {{{ isElementFrozen()
}
/**
* Returns whether or not the form element is frozen
@ -1380,10 +1338,7 @@ class HTML_QuickForm extends HTML_Common
return $this->_elements[$this->_elementIndex[$element]]->isFrozen();
}
return false;
} // end func isElementFrozen
// }}}
// {{{ setJsWarnings()
}
/**
* Sets JavaScript warning messages
@ -1398,10 +1353,7 @@ class HTML_QuickForm extends HTML_Common
{
$this->_jsPrefix = $pref;
$this->_jsPostfix = $post;
} // end func setJsWarnings
// }}}
// {{{ setRequiredNote()
}
/**
* Sets required-note
@ -1414,10 +1366,7 @@ class HTML_QuickForm extends HTML_Common
function setRequiredNote($note)
{
$this->_requiredNote = $note;
} // end func setRequiredNote
// }}}
// {{{ getRequiredNote()
}
/**
* Returns the required note

@ -33,20 +33,6 @@
*/
class HTML_QuickForm_input extends HTML_QuickForm_element
{
/**
* Class constructor
*
* @param string Input field name attribute
* @param mixed Label(s) for the input field
* @param mixed Either a typical HTML attribute string or an associative array
* @since 1.0
* @access public
* @return void
*/
public function __construct($elementName=null, $elementLabel=null, $attributes=null)
{
parent::__construct($elementName, $elementLabel, $attributes);
}
/**
* Sets the element type
@ -56,7 +42,7 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
* @access public
* @return void
*/
function setType($type)
public function setType($type)
{
$this->_type = $type;
$this->updateAttributes(array('type'=>$type));
@ -70,7 +56,7 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
* @access public
* @return void
*/
function setName($name)
public function setName($name)
{
$this->updateAttributes(array('name'=>$name));
}
@ -82,7 +68,7 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
* @access public
* @return string
*/
function getName()
public function getName()
{
return $this->getAttribute('name');
}
@ -139,7 +125,7 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
* @return void
* @throws
*/
function onQuickFormEvent($event, $arg, &$caller)
public function onQuickFormEvent($event, $arg, &$caller)
{
// do not use submit values for button-type elements
$type = $this->getType();
@ -161,7 +147,7 @@ class HTML_QuickForm_input extends HTML_QuickForm_element
/**
* We don't need values from button-type elements (except submit) and files
*/
function exportValue(&$submitValues, $assoc = false)
public function exportValue(&$submitValues, $assoc = false)
{
$type = $this->getType();
if ('reset' == $type || 'image' == $type || 'button' == $type || 'file' == $type) {

@ -1063,6 +1063,7 @@ class SocialManager extends UserManager
</a>
</li>';
$links .= $personalData;
$links .= '</ul>';
}
@ -1087,7 +1088,7 @@ class SocialManager extends UserManager
if ($show === 'shared_profile') {
$links = '<ul class="nav nav-pills nav-stacked">';
// My own profile
if ($show_full_profile && $user_id == intval(api_get_user_id())) {
if ($show_full_profile && $user_id == api_get_user_id()) {
$links .= '
<li class="home-icon '.$active.'">
<a href="'.api_get_path(WEB_CODE_PATH).'social/home.php">
@ -1155,6 +1156,18 @@ class SocialManager extends UserManager
</li>
';
}
if (!api_get_configuration_value('disable_gdpr')) {
$active = $show == 'personal-data' ? 'active' : null;
$personalData = '
<li class="personal-data-icon '.$active.'">
<a href="'.api_get_path(WEB_CODE_PATH).'social/personal_data.php">
'.$personalDataIcon.' '.get_lang('PersonalDataReport').'
</a>
</li>';
$links .= $personalData;
$links .= '</ul>';
}
}
// My friend profile.
@ -1220,7 +1233,7 @@ class SocialManager extends UserManager
'sn-sidebar-collapse'
);
if ($show_full_profile && $user_id == intval(api_get_user_id())) {
if ($show_full_profile && $user_id == api_get_user_id()) {
$personal_course_list = UserManager::get_personal_session_course_list($user_id);
$course_list_code = [];
$i = 1;
@ -1238,14 +1251,13 @@ class SocialManager extends UserManager
}
// Announcements
$my_announcement_by_user_id = intval($user_id);
$announcements = [];
foreach ($course_list_code as $course) {
$course_info = api_get_course_info($course['code']);
if (!empty($course_info)) {
$content = AnnouncementManager::get_all_annoucement_by_user_course(
$course_info['code'],
$my_announcement_by_user_id
$user_id
);
if (!empty($content)) {

@ -1149,4 +1149,135 @@ class Statistics
return $chartCode;
}
/**
* Display the Logins By Date report and allow export its result to XLS.
*/
public static function printLoginsByDate()
{
if (isset($_GET['export']) && 'xls' === $_GET['export']) {
$result = self::getLoginsByDate($_GET['start'], $_GET['end']);
$data = [[get_lang('Username'), get_lang('FirstName'), get_lang('LastName'), get_lang('TotalTime')]];
foreach ($result as $i => $item) {
$data[] = [
$item['username'],
$item['firstname'],
$item['lastname'],
api_time_to_hms($item['time_count']),
];
}
Export::arrayToXls($data);
exit;
}
echo Display::page_header(get_lang('LoginsByDate'));
$actions = '';
$content = '';
$form = new FormValidator('frm_logins_by_date', 'get');
$form->addDateRangePicker(
'daterange',
get_lang('DateRange'),
true,
['format' => 'YYYY-MM-DD', 'timePicker' => 'false', 'validate_format' => 'Y-m-d']
);
$form->addHidden('report', 'logins_by_date');
$form->addButtonFilter(get_lang('Search'));
if ($form->validate()) {
$values = $form->exportValues();
$result = self::getLoginsByDate($values['daterange_start'], $values['daterange_end']);
if (!empty($result)) {
$actions = Display::url(
Display::return_icon('excel.png', get_lang('ExportToXls'), [], ICON_SIZE_MEDIUM),
api_get_self().'?'.http_build_query(
[
'report' => 'logins_by_date',
'export' => 'xls',
'start' => Security::remove_XSS($values['daterange_start']),
'end' => Security::remove_XSS($values['daterange_end']),
]
)
);
}
$table = new HTML_Table(['class' => 'data_table']);
$table->setHeaderContents(0, 0, get_lang('Username'));
$table->setHeaderContents(0, 1, get_lang('FirstName'));
$table->setHeaderContents(0, 2, get_lang('LastName'));
$table->setHeaderContents(0, 3, get_lang('TotalTime'));
foreach ($result as $i => $item) {
$table->setCellContents($i + 1, 0, $item['username']);
$table->setCellContents($i + 1, 1, $item['firstname']);
$table->setCellContents($i + 1, 2, $item['lastname']);
$table->setCellContents($i + 1, 3, api_time_to_hms($item['time_count']));
}
$table->setColAttributes(0, ['class' => 'text-center']);
$table->setColAttributes(3, ['class' => 'text-center']);
$content = $table->toHtml();
}
$form->display();
if (!empty($actions)) {
echo Display::toolbarAction('logins_by_date_toolbar', [$actions]);
}
echo $content;
}
/**
* @param string $startDate
* @param string $endDate
*
* @return array
*/
private static function getLoginsByDate($startDate, $endDate)
{
/** @var DateTime $startDate */
$startDate = api_get_utc_datetime("$startDate 00:00:00");
/** @var DateTime $endDate */
$endDate = api_get_utc_datetime("$endDate 23:59:59");
if (empty($startDate) || empty($endDate)) {
return [];
}
$tblUser = Database::get_main_table(TABLE_MAIN_USER);
$tblLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
$urlJoin = '';
$urlWhere = '';
if (api_is_multiple_url_enabled()) {
$tblUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
$urlJoin = "INNER JOIN $tblUrlUser au ON u.id = au.user_id";
$urlWhere = 'AND au.access_url_id = '.api_get_current_access_url_id();
}
$sql = "SELECT u.id,
u.firstname,
u.lastname,
u.username,
SUM(TIMESTAMPDIFF(SECOND, l.login_date, l.logout_date)) AS time_count
FROM $tblUser u
INNER JOIN $tblLogin l ON u.id = l.login_user_id
$urlJoin
WHERE l.login_date BETWEEN '$startDate' AND '$endDate'
$urlWhere
GROUP BY u.id";
$stmt = Database::query($sql);
$result = Database::store_result($stmt, 'ASSOC');
return $result;
}
}

@ -563,7 +563,7 @@ class Tracking
}
if ($extend_this_attempt || $extend_all) {
$list1 = learnpath::get_iv_interactions_array($row['iv_id']);
$list1 = learnpath::get_iv_interactions_array($row['iv_id'], $course_id);
foreach ($list1 as $id => $interaction) {
$oddclass = 'row_even';
if (($counter % 2) == 0) {
@ -591,7 +591,7 @@ class Tracking
</tr>';
$counter++;
}
$list2 = learnpath::get_iv_objectives_array($row['iv_id']);
$list2 = learnpath::get_iv_objectives_array($row['iv_id'], $course_id);
foreach ($list2 as $id => $interaction) {
if (($counter % 2) == 0) {
$oddclass = 'row_odd';
@ -951,7 +951,7 @@ class Tracking
}
if ($extend_this_attempt || $extend_all) {
$list1 = learnpath::get_iv_interactions_array($row['iv_id']);
$list1 = learnpath::get_iv_interactions_array($row['iv_id'], $course_id);
foreach ($list1 as $id => $interaction) {
if (($counter % 2) == 0) {
$oddclass = 'row_odd';
@ -979,7 +979,7 @@ class Tracking
</tr>';
$counter++;
}
$list2 = learnpath::get_iv_objectives_array($row['iv_id']);
$list2 = learnpath::get_iv_objectives_array($row['iv_id'], $course_id);
foreach ($list2 as $id => $interaction) {
if (($counter % 2) == 0) {

@ -20,7 +20,6 @@
*/
require_once __DIR__.'/../inc/global.inc.php';
$current_course_tool = TOOL_LINK;
$this_section = SECTION_COURSES;
api_protect_course_script(true);
@ -93,7 +92,7 @@ Event::event_access_tool(TOOL_LINK);
$id = isset($_REQUEST['id']) ? $_REQUEST['id'] : null;
$scope = isset($_REQUEST['scope']) ? $_REQUEST['scope'] : null;
$show = isset($_REQUEST['show']) && in_array(trim($_REQUEST['show']), ['all', 'none']) ? $_REQUEST['show'] : '';
$categoryId = isset($_REQUEST['category_id']) ? intval($_REQUEST['category_id']) : '';
$categoryId = isset($_REQUEST['category_id']) ? (int) $_REQUEST['category_id'] : '';
$linkListUrl = api_get_self().'?'.api_get_cidreq().'&category_id='.$categoryId.'&show='.$show;
$content = '';
$token = Security::get_existing_token();
@ -212,11 +211,24 @@ switch ($action) {
header('Location: '.$linkListUrl);
exit;
break;
case 'export':
$content = Link::listLinksAndCategories($course_id, $session_id, $categoryId, $show, null, false);
$pdf = new PDF();
$pdf->content_to_pdf(
$content,
null,
$courseInfo['code'].get_lang('Link'),
$courseInfo['code'],
'D',
false,
null,
false,
true
);
break;
case 'list':
default:
ob_start();
Link::listLinksAndCategories($course_id, $session_id, $categoryId, $show);
$content = ob_get_clean();
$content = Link::listLinksAndCategories($course_id, $session_id, $categoryId, $show);
break;
}

@ -3009,13 +3009,14 @@ class learnpath
*
* @todo Transcode labels instead of switching to HTML (which requires to know the encoding of the LP)
*/
public static function get_iv_interactions_array($lp_iv_id)
public static function get_iv_interactions_array($lp_iv_id, $course_id = 0)
{
$course_id = api_get_course_int_id();
$course_id = empty($course_id) ? api_get_course_int_id() : (int) $course_id;
$list = [];
$table = Database::get_course_table(TABLE_LP_IV_INTERACTION);
$lp_iv_id = (int) $lp_iv_id;
if (empty($lp_iv_id)) {
if (empty($lp_iv_id) || empty($course_id)) {
return [];
}
@ -3034,18 +3035,29 @@ class learnpath
'student_response' => api_htmlentities(get_lang('StudentResponse'), ENT_QUOTES),
'result' => api_htmlentities(get_lang('Result'), ENT_QUOTES),
'latency' => api_htmlentities(get_lang('LatencyTimeSpent'), ENT_QUOTES),
'student_response_formatted' => '',
];
while ($row = Database::fetch_array($res)) {
$studentResponseFormatted = urldecode($row['student_response']);
$content_student_response = explode('__|', $studentResponseFormatted);
if (count($content_student_response) > 0) {
if (count($content_student_response) >= 3) {
// Pop the element off the end of array.
array_pop($content_student_response);
}
$studentResponseFormatted = implode(',', $content_student_response);
}
$list[] = [
'order_id' => ($row['order_id'] + 1),
'order_id' => $row['order_id'] + 1,
'id' => urldecode($row['interaction_id']), //urldecode because they often have %2F or stuff like that
'type' => $row['interaction_type'],
'time' => $row['completion_time'],
//'correct_responses' => $row['correct_responses'],
'correct_responses' => '', // Hide correct responses from students.
'student_response' => $row['student_response'],
'result' => $row['result'],
'latency' => $row['latency'],
'student_response_formatted' => $studentResponseFormatted,
];
}
}
@ -3085,16 +3097,21 @@ class learnpath
* This method can be used as static.
*
* @param int $lpItemViewId Learnpath Item View ID
* @param int $course_id
*
* @return array
*
* @todo Translate labels
*/
public static function get_iv_objectives_array($lpItemViewId = 0)
public static function get_iv_objectives_array($lpItemViewId = 0, $course_id = 0)
{
$course_id = api_get_course_int_id();
$course_id = empty($course_id) ? api_get_course_int_id() : (int) $course_id;
$lpItemViewId = (int) $lpItemViewId;
if (empty($course_id) || empty($lpItemViewId)) {
return [];
}
$table = Database::get_course_table(TABLE_LP_IV_OBJECTIVE);
$sql = "SELECT * FROM $table
WHERE c_id = $course_id AND lp_iv_id = $lpItemViewId
@ -3113,7 +3130,7 @@ class learnpath
];
while ($row = Database::fetch_array($res)) {
$list[] = [
'order_id' => ($row['order_id'] + 1),
'order_id' => $row['order_id'] + 1,
'objective_id' => urldecode($row['objective_id']), // urldecode() because they often have %2F
'score_raw' => $row['score_raw'],
'score_max' => $row['score_max'],
@ -8101,8 +8118,8 @@ class learnpath
$item_title = stripslashes($extra_info['title']);
} elseif (is_numeric($extra_info)) {
$sql = "SELECT forum_title as title, forum_comment as comment
FROM ".$tbl_forum."
WHERE c_id = ".$course_id." AND forum_id = ".$extra_info;
FROM $tbl_forum
WHERE c_id = $course_id AND forum_id = ".$extra_info;
$result = Database::query($sql);
$row = Database::fetch_array($result);
@ -10038,30 +10055,6 @@ class learnpath
$_course = api_get_course_info();
$course_code = api_get_course_id();
$return = '<div class="actions">';
switch ($item_type) {
case 'dir':
// Commented the message cause should not show it.
//$lang = get_lang('TitleManipulateChapter');
break;
case TOOL_LP_FINAL_ITEM:
case TOOL_DOCUMENT:
// Commented the message cause should not show it.
//$lang = get_lang('TitleManipulateDocument');
break;
case TOOL_LINK:
case 'link':
// Commented the message cause should not show it.
//$lang = get_lang('TitleManipulateLink');
break;
case TOOL_QUIZ:
// Commented the message cause should not show it.
//$lang = get_lang('TitleManipulateQuiz');
break;
case TOOL_STUDENTPUBLICATION:
// Commented the message cause should not show it.
//$lang = get_lang('TitleManipulateStudentPublication');
break;
}
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$item_id = (int) $item_id;
@ -10251,6 +10244,7 @@ class learnpath
{
$return = '';
if (is_numeric($item_id)) {
$item_id = (int) $item_id;
$tbl_lp_item = Database::get_course_table(TABLE_LP_ITEM);
$sql = "SELECT * FROM $tbl_lp_item
@ -10603,7 +10597,7 @@ class learnpath
$form->createElement(
'radio',
'if_exists',
get_lang("UplWhatIfFileExists"),
get_lang('UplWhatIfFileExists'),
get_lang('UplDoNothing'),
'nothing'
),
@ -10791,7 +10785,7 @@ class learnpath
$session_id,
true,
true,
"link.session_id"
'link.session_id'
);
$sql = "SELECT
@ -10803,7 +10797,7 @@ class learnpath
FROM $tbl_link as link
LEFT JOIN $linkCategoryTable as link_category
ON (link.category_id = link_category.id AND link.c_id = link_category.c_id)
WHERE link.c_id = ".$course_id." $condition_session
WHERE link.c_id = $course_id $condition_session
ORDER BY link_category.category_title ASC, link.title ASC";
$result = Database::query($sql);
$categorizedLinks = [];
@ -12048,7 +12042,10 @@ EOD;
{
$lp_id = (int) $lp_id;
$files_to_export = [];
$sessionId = api_get_session_id();
$course_data = api_get_course_info($this->cc);
if (!empty($course_data)) {
$scorm_path = api_get_path(SYS_COURSE_PATH).$course_data['path'].'/scorm/'.$this->path;
$list = self::get_flat_ordered_items_list($lp_id);
@ -12057,7 +12054,7 @@ EOD;
$item = $this->items[$item_id];
switch ($item->type) {
case 'document':
//Getting documents from a LP with chamilo documents
// Getting documents from a LP with chamilo documents
$file_data = DocumentManager::get_document_data_by_id($item->path, $this->cc);
// Try loading document from the base course.
if (empty($file_data) && !empty($sessionId)) {
@ -12095,12 +12092,16 @@ EOD;
}
}
}
$pdf = new PDF();
$result = $pdf->html_to_pdf(
$files_to_export,
$this->name,
$this->cc,
true
true,
true,
true,
$this->get_name()
);
return $result;
@ -12214,8 +12215,8 @@ EOD;
public function set_autolaunch($lp_id, $status)
{
$course_id = api_get_course_int_id();
$lp_id = intval($lp_id);
$status = intval($status);
$lp_id = (int) $lp_id;
$status = (int) $status;
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
// Setting everything to autolaunch = 0
@ -12527,11 +12528,6 @@ EOD;
public static function getCategories($courseId)
{
$em = Database::getManager();
//Default behaviour
/*$items = $em->getRepository('ChamiloCourseBundle:CLpCategory')->findBy(
array('cId' => $course_id),
array('name' => 'ASC')
);*/
// Using doctrine extensions
/** @var SortableRepository $repo */
@ -13121,7 +13117,7 @@ EOD;
'lp_id' => $this->lp_id,
'forum_title' => $this->name,
'forum_comment' => null,
'forum_category' => intval($forumCategoryId),
'forum_category' => (int) $forumCategoryId,
'students_can_edit_group' => ['students_can_edit' => 0],
'allow_new_threads_group' => ['allow_new_threads' => 0],
'default_view_type_group' => ['default_view_type' => 'flat'],
@ -13303,7 +13299,7 @@ EOD;
if ($this->debug > 0) {
error_log('In learnpath::setAccumulateScormTime()', 0);
}
$this->accumulateScormTime = intval($value);
$this->accumulateScormTime = (int) $value;
$lp_table = Database::get_course_table(TABLE_LP_MAIN);
$lp_id = $this->get_id();
$sql = "UPDATE $lp_table
@ -14009,6 +14005,11 @@ EOD;
return $icon;
}
/**
* @param int $lpId
*
* @return string
*/
public static function getSelectedIconHtml($lpId)
{
$icon = self::getSelectedIcon($lpId);

@ -87,6 +87,10 @@ $suredel = trim(get_lang('AreYouSureToDeleteJS'));
$lpPathInfo = $lp->generate_lp_folder(api_get_course_info());
DocumentManager::createDefaultAudioFolder($courseInfo);
$audioFolderId = DocumentManager::get_document_id($courseInfo, '/audio');
$file = null;
if (isset($lp_item->audio) && !empty($lp_item->audio)) {
$file = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document/audio/'.$lp_item->audio;

@ -37,7 +37,7 @@ if (api_get_configuration_value('save_titles_as_html')) {
get_lang('Name'),
true,
false,
['ToolbarSet' => 'Minimal']
['ToolbarSet' => 'Minimal', 'Height' => '100']
);
} else {
$form->addText('name', get_lang('Name'), true);

@ -888,14 +888,18 @@ switch ($action) {
}
break;
case 'export_to_pdf':
if (!learnpath::is_lp_visible_for_student($_SESSION['oLP']->lp_id, api_get_user_id())) {
api_not_allowed();
}
$hideScormPdfLink = api_get_setting('hide_scorm_pdf_link');
if ($hideScormPdfLink === 'true') {
api_not_allowed(true);
}
// Teachers can export to PDF
if (!$is_allowed_to_edit) {
if (!learnpath::is_lp_visible_for_student($_SESSION['oLP']->lp_id, api_get_user_id())) {
api_not_allowed();
}
}
if (!$lp_found) {
require 'lp_list.php';
} else {

@ -25,7 +25,7 @@ $extendId = isset($_GET['extend_id']) ? $_GET['extend_id'] : null;
$extendAttemptId = isset($_GET['extend_attempt_id']) ? $_GET['extend_attempt_id'] : null;
$extendedAttempt = isset($_GET['extend_attempt']) ? $_GET['extend_attempt'] : null;
$extendedAll = isset($_GET['extend_all']) ? $_GET['extend_all'] : null;
$export = isset($_GET['export']) && $_GET['export'] === 'csv' ? true : false;
$export = isset($_GET['export']) && $_GET['export'] === 'csv';
$allowExtend = isset($_GET['allow_extend']) ? $_GET['allow_extend'] : 1;
$lpReportType = api_get_setting('lp_show_reduced_report');

@ -60,7 +60,7 @@ function add_image_form() {
</script>';
$nameTools = get_lang('ComposeMessage');
$tpl = new Template($nameTools);
$tpl = new Template(get_lang('ComposeMessage'));
/**
* Shows the compose area + a list of users to select from.
@ -179,7 +179,7 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '', $tpl
get_lang('Message'),
false,
false,
['ToolbarSet' => 'Messages', 'Width' => '100%', 'Height' => '250']
['ToolbarSet' => 'Messages', 'Width' => '100%', 'Height' => '250', 'style' => true]
);
if (isset($_GET['re_id'])) {
@ -191,10 +191,10 @@ function manageForm($default, $select_from_user_list = null, $sent_to = '', $tpl
// Adding reply mail
$user_reply_info = api_get_user_info($message_reply_info['user_sender_id']);
$default['content'] = '<p><br/></p>'.sprintf(
get_lang('XWroteY'),
$user_reply_info['complete_name'],
Security::filter_terms($message_reply_info['content'])
);
get_lang('XWroteY'),
$user_reply_info['complete_name'],
Security::filter_terms($message_reply_info['content'])
);
}
if (isset($_GET['forward_id'])) {

@ -1,5 +1,9 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\CoreBundle\Component\Utils\ChamiloApi;
use Chamilo\CourseBundle\Entity\CLpItemView;
/**
* Learning paths reporting.
*
@ -7,7 +11,6 @@
*/
require_once __DIR__.'/../inc/global.inc.php';
// resetting the course id
$cidReset = true;
$from_myspace = false;
$from_link = '';
@ -18,18 +21,16 @@ if (isset($_GET['from']) && $_GET['from'] == 'myspace') {
$this_section = SECTION_COURSES;
}
$session_id = isset($_REQUEST['id_session']) && !empty($_REQUEST['id_session'])
? intval($_REQUEST['id_session'])
: api_get_session_id();
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv' ? true : false;
$user_id = isset($_GET['student_id']) ? intval($_GET['student_id']) : api_get_user_id();
$session_id = isset($_REQUEST['id_session']) ? (int) $_REQUEST['id_session'] : api_get_session_id();
$export_csv = isset($_GET['export']) && $_GET['export'] == 'csv';
$user_id = isset($_GET['student_id']) ? (int) $_GET['student_id'] : api_get_user_id();
$courseCode = isset($_GET['course']) ? Security::remove_XSS($_GET['course']) : api_get_course_id();
$origin = api_get_origin();
$lp_id = intval($_GET['lp_id']);
$lp_id = (int) $_GET['lp_id'];
$csv_content = [];
$course_info = api_get_course_info($courseCode);
$courseInfo = api_get_course_info($courseCode);
if (empty($course_info) || empty($lp_id)) {
if (empty($courseInfo) || empty($lp_id)) {
api_not_allowed(api_get_origin() !== 'learnpath');
}
$userInfo = api_get_user_info($user_id);
@ -43,44 +44,238 @@ if (!api_is_platform_admin(true) &&
!api_is_drh() &&
!api_is_course_tutor()
) {
api_not_allowed(
api_get_origin() !== 'learnpath'
);
api_not_allowed(api_get_origin() !== 'learnpath');
}
if ($origin == 'user_course') {
if ($origin === 'user_course') {
$interbreadcrumb[] = [
'url' => api_get_path(WEB_COURSE_PATH).$course_info['directory'],
'name' => $course_info['name'],
'url' => api_get_path(WEB_COURSE_PATH).$courseInfo['directory'],
'name' => $courseInfo['name'],
];
$interbreadcrumb[] = [
'url' => "../user/user.php?cidReq=$courseCode",
'name' => get_lang("Users"),
'name' => get_lang('Users'),
];
} elseif ($origin == 'tracking_course') {
} elseif ($origin === 'tracking_course') {
$interbreadcrumb[] = [
'url' => "../tracking/courseLog.php?cidReq=$courseCode&id_session=$session_id",
'name' => get_lang("Tracking"),
'name' => get_lang('Tracking'),
];
} else {
$interbreadcrumb[] = ['url' => 'index.php', 'name' => get_lang('MySpace')];
$interbreadcrumb[] = ['url' => 'student.php', 'name' => get_lang("MyStudents")];
$interbreadcrumb[] = ['url' => "myStudents.php?student=$user_id", 'name' => get_lang("StudentDetails")];
$nameTools = get_lang("DetailsStudentInCourse");
$interbreadcrumb[] = ['url' => 'student.php', 'name' => get_lang('MyStudents')];
$interbreadcrumb[] = ['url' => "myStudents.php?student=$user_id", 'name' => get_lang('StudentDetails')];
$nameTools = get_lang('DetailsStudentInCourse');
}
$interbreadcrumb[] = [
'url' => "myStudents.php?student=$user_id&course=$courseCode&details=true&origin=$origin",
'name' => get_lang("DetailsStudentInCourse"),
'name' => get_lang('DetailsStudentInCourse'),
];
$nameTools = get_lang('LearningPathDetails');
$sql = 'SELECT name FROM '.Database::get_course_table(TABLE_LP_MAIN).'
WHERE c_id = '.$course_info['real_id'].' AND id='.$lp_id;
WHERE c_id = '.$courseInfo['real_id'].' AND id='.$lp_id;
$rs = Database::query($sql);
$lp_title = Database::result($rs, 0, 0);
$origin = 'tracking';
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
switch ($action) {
case 'export_stats':
if (!api_is_allowed_to_edit()) {
api_not_allowed();
}
$tpl = new Template(null, false, false);
$itemId = isset($_REQUEST['extend_id']) ? $_REQUEST['extend_id'] : 0;
$itemViewId = isset($_REQUEST['extend_attempt_id']) ? $_REQUEST['extend_attempt_id'] : 0;
$em = Database::getManager();
$repo = $em->getRepository('ChamiloCourseBundle:CLpItemView');
/** @var CLpItemView $itemView */
$itemView = $repo->find($itemViewId);
if (!$itemView) {
api_not_allowed();
}
$view = $em->getRepository('ChamiloCourseBundle:CLpView')->find($itemView->getLpViewId());
$lp = $em->getRepository('ChamiloCourseBundle:CLp')->find($view->getLpId());
$duration = learnpathItem::getScormTimeFromParameter('js', $itemView->getTotalTime());
$endTime = $itemView->getStartTime() + $itemView->getTotalTime();
$list1 = learnpath::get_iv_interactions_array($itemViewId, $courseInfo['real_id']);
$counter = 0;
$table = new HTML_Table();
$total = 0;
$numberChoices = 0;
$questionCounter = 0;
$studentName = '';
$questions = [];
$categories = [];
foreach ($list1 as $id => $interaction) {
$counter++;
if ($counter === 1) {
continue;
} elseif ($counter === 2) {
$studentName = $interaction['student_response_formatted'];
} else {
$data = $interaction['student_response_formatted'];
switch ($interaction['type']) {
case 'fill-in':
$questionCounter++;
$questions[$questionCounter]['question'] = $data;
break;
case 'choice':
$questions[$questionCounter]['options'][] = $interaction;
$numberChoices++;
break;
case 'matching':
$list = explode(',', $data);
if (!empty($list)) {
foreach ($list as &$item) {
$item = cut($item, 30);
}
$interaction['student_response_formatted'] = implode('<br />', $list);
}
$questions[$questionCounter]['options'][] = $interaction;
$numberChoices++;
break;
}
}
}
$counter = 1;
$table = new HTML_Table(['class' => 'table data_table']);
$row = 0;
$scoreDisplay = new ScoreDisplay();
$globalTotal = 0;
$globalTotalCount = 0;
foreach ($questions as $data) {
// Question title
$table->setCellContents($row, 0, $data['question']);
$table->setCellAttributes($row, 0, ['colspan' => '3', 'style' => 'text-align:center; font-weight:bold']);
$choiceCounter = 1;
$row++;
$total = 0;
// Question options
foreach ($data['options'] as $option) {
if ($option['result'] === 'correct') {
$total++;
$globalTotal++;
}
$table->setCellContents($row, 0, 'Q'.$choiceCounter);
$table->setCellContents($row, 1, $option['student_response_formatted']);
$result = Display::return_icon('icon_check.png', null, [], ICON_SIZE_SMALL);
if ($option['result'] === 'wrong') {
$result = Display::return_icon('icon_error.png', null, [], ICON_SIZE_SMALL);
}
$table->setCellContents($row, 2, $result);
$choiceCounter++;
$row++;
}
// Question total
$table->setCellContents($row, 0, get_lang('Total'));
$table->setCellContents($row, 1, $data['question']);
$totalOptions = count($data['options']);
$arrayScore = [0 => $total, 1 => $totalOptions];
$scoreToString = $scoreDisplay->display_score($arrayScore);
$table->setCellContents($row, 2, $scoreToString);
$table->setCellAttributes($row, 0, ['style' => 'font-weight:bold']);
$table->setCellAttributes($row, 1, ['style' => 'font-weight:bold']);
$table->setCellAttributes($row, 2, ['style' => 'font-weight:bold']);
$categories[] = [
'name' => $data['question'],
'score' => $scoreDisplay->display_score($arrayScore, SCORE_DIV),
'score_numeric' => $scoreDisplay->display_score($arrayScore, SCORE_NUMERIC),
'score_percentage' => $scoreDisplay->display_score($arrayScore, SCORE_PERCENT),
];
$tpl->assign('categories', $categories);
$globalTotalCount += $totalOptions;
$row++;
}
$globalScoreTotal = [0 => $globalTotal, 1 => $globalTotalCount];
$score = $scoreDisplay->display_score($globalScoreTotal);
$generalScore[] = [
'score' => $scoreDisplay->display_score($globalScoreTotal, SCORE_DIV),
'score_numeric' => $scoreDisplay->display_score($globalScoreTotal, SCORE_NUMERIC),
'score_percentage' => $scoreDisplay->display_score($globalScoreTotal, SCORE_PERCENT),
];
$tpl->assign('general_score', $generalScore);
$tpl->assign('global_total', $score);
$tableToString = $table->toHtml();
$duration = learnpathItem::getScormTimeFromParameter('js', $itemView->getTotalTime());
$dataLpInfo = [
'name' => $lp->getName(),
'attempt' => $itemView->getViewCount(),
'score' => $score,
'duration' => $duration,
'start_time' => api_get_local_time($itemView->getStartTime()),
'start_date' => api_get_local_time($itemView->getStartTime(), null, null, null, false),
'end_time' => api_get_local_time($endTime),
'candidate' => $studentName,
];
$tpl->assign('data', $dataLpInfo);
$contentText = $tpl->fetch($tpl->get_template('my_space/pdf_tracking_lp.tpl'));
$content = $contentText.'<pagebreak>'.$tableToString;
$pdf = new PDF('A4', 'P', ['margin_footer' => 4, 'top' => 40, 'bottom' => 25]);
$table = new HTML_Table(['class' => 'table', 'style' => 'display: block; margin-bottom: 50px;']);
$logo = ChamiloApi::getPlatformLogo(
$theme,
[
'title' => '',
'style' => 'max-width:180px, margin-bottom: 100px;',
'id' => 'header-logo',
]
);
$table->setCellContents(0, 0, $logo);
$secondLogo = api_get_path(SYS_PATH).'custompages/url-images/'.api_get_current_access_url_id().'_url_image_2.png';
$logo2 = Display::img($secondLogo, null, ['style' => 'height:70px;']);
$table->setCellContents(0, 1, $logo2);
$table->setCellAttributes(0, 1, ['style' => 'display:block;float:right;text-align:right']);
$pdf->set_custom_header($table->toHtml());
$background = api_get_path(SYS_PATH).'custompages/url-images/'.api_get_current_access_url_id().'_pdf_background.png';
$content =
'<html>
<body style="background-image-resize: 5; background-position: top left; background-image: url('.$background.');">'
.$content.'</body></html>';
$pdf->content_to_pdf(
$content,
null,
$courseInfo['code'].'_'.$lp->getName().'_'.api_get_local_time(),
$courseInfo['code'],
'D',
false,
null,
false,
true
);
break;
}
$output = require_once api_get_path(SYS_CODE_PATH).'lp/lp_stats.php';
$actions = [];
@ -106,7 +301,7 @@ echo Display::toolbarAction(
$table_title = $session_id
? Display::return_icon('session.png', get_lang('Session')).PHP_EOL.api_get_session_name($session_id).PHP_EOL
: PHP_EOL;
$table_title .= Display::return_icon('course.png', get_lang('Course')).PHP_EOL.$course_info['name'].PHP_EOL
$table_title .= Display::return_icon('course.png', get_lang('Course')).PHP_EOL.$courseInfo['name'].PHP_EOL
.Display::return_icon('user.png', get_lang('User')).' '.$name;
echo Display::page_header($table_title);

@ -14,13 +14,13 @@ api_block_anonymous_users();
$this_section = SECTION_TRACKING;
$export_csv = false;
if (isset($_GET['export']) && $_GET['export'] == 'csv') {
if (isset($_REQUEST['export']) && $_REQUEST['export'] == 'csv') {
$export_csv = true;
}
$id_coach = api_get_user_id();
if (isset($_GET['id_coach']) && $_GET['id_coach'] != '') {
$id_coach = (int) $_GET['id_coach'];
if (isset($_REQUEST['id_coach']) && $_REQUEST['id_coach'] != '') {
$id_coach = (int) $_REQUEST['id_coach'];
}
$allowToTrack = api_is_platform_admin(true, true) || api_is_teacher();
@ -121,59 +121,224 @@ if (api_is_platform_admin(true, true)) {
$form = new FormValidator(
'search_course',
'get',
'post',
api_get_path(WEB_CODE_PATH).'mySpace/session.php'
);
$form->addElement('text', 'keyword', get_lang('Keyword'));
$extraFieldSession = new ExtraField('session');
$extraFieldSession->addElements(
$form,
null,
[], //exclude
true
);
$form->addButtonSearch(get_lang('Search'));
$keyword = '';
$result = SessionManager::getGridColumns('my_space');
$columns = $result['columns'];
$columnModel = $result['column_model'];
$filterToString = '';
if ($form->validate()) {
$keyword = $form->getSubmitValue('keyword');
$values = $form->getSubmitValues();
$keyword = Security::remove_XSS($form->getSubmitValue('keyword'));
$extraField = new ExtraField('session');
$extraFields = $extraField->get_all(null, 'option_order');
$extraFields = array_column($extraFields, 'variable');
$filter = new stdClass();
$filter->groupOp = 'AND';
foreach ($columnModel as $col) {
if (isset($values[$col['index']]) && !empty($values[$col['index']]) &&
in_array(str_replace('extra_', '', $col['index']), $extraFields)
) {
$rule = new stdClass();
$rule->field = $col['index'];
$rule->op = 'in';
$rule->data = Security::remove_XSS($values[$col['index']]);
$filter->rules[] = $rule;
$filter->groupOp = 'AND';
}
}
$filterToString = json_encode($filter);
}
$form->setDefaults(['keyword' => $keyword]);
$url = api_get_path(WEB_AJAX_PATH).'model.ajax.php?a=get_sessions_tracking&keyword='.Security::remove_XSS($keyword);
$columns = [
get_lang('Title'),
get_lang('Date'),
get_lang('NbCoursesPerSession'),
get_lang('NbStudentPerSession'),
get_lang('Details'),
];
$url = api_get_path(WEB_AJAX_PATH).
'model.ajax.php?a=get_sessions_tracking&_search=true&_force_search=true&filters='.$filterToString.'&keyword='.$keyword;
// Column config
$columnModel = [
['name' => 'name', 'index' => 'name', 'width' => '255', 'align' => 'left'],
['name' => 'date', 'index' => 'access_start_date', 'width' => '150', 'align' => 'left'],
['name' => 'course_per_session', 'index' => 'course_per_session', 'width' => '150', 'sortable' => 'false'],
['name' => 'student_per_session', 'index' => 'student_per_session', 'width' => '100', 'sortable' => 'false'],
['name' => 'details', 'index' => 'details', 'width' => '100', 'sortable' => 'false'],
];
$extraParams = [
'autowidth' => 'true',
'height' => 'auto',
];
$js = '<script>
$(function() {
'.Display::grid_js(
'session_tracking',
$url,
$columns,
$columnModel,
$extraParams,
[],
null,
true
).'
});
</script>';
echo $js;
/*$extraParams['postData'] = [
'filters' => [
'groupOp' => 'AND',
'rules' => $result['rules'],
],
];*/
$urlAjaxExtraField = api_get_path(WEB_AJAX_PATH).'extra_field.ajax.php?1=1';
$allowOrder = api_get_configuration_value('session_list_order');
$orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
?>
<script>
function setSearchSelect(columnName) {
$("#sessions").jqGrid('setColProp', columnName, {
});
}
var added_cols = [];
var original_cols = [];
function clean_cols(grid, added_cols) {
// Cleaning
for (key in added_cols) {
grid.hideCol(key);
};
grid.showCol('name');
grid.showCol('display_start_date');
grid.showCol('display_end_date');
grid.showCol('course_title');
}
function show_cols(grid, added_cols) {
grid.showCol('name').trigger('reloadGrid');
for (key in added_cols) {
grid.showCol(key);
};
}
var second_filters = [];
$(function() {
date_pick_today = function(elem) {
$(elem).datetimepicker({dateFormat: "yy-mm-dd"});
$(elem).datetimepicker('setDate', (new Date()));
}
date_pick_one_month = function(elem) {
$(elem).datetimepicker({dateFormat: "yy-mm-dd"});
next_month = Date.today().next().month();
$(elem).datetimepicker('setDate', next_month);
}
// Great hack
register_second_select = function(elem) {
second_filters[$(elem).val()] = $(elem);
}
fill_second_select = function(elem) {
$(elem).on("change", function() {
composed_id = $(this).val();
field_id = composed_id.split("#")[0];
id = composed_id.split("#")[1];
$.ajax({
url: "<?php echo $urlAjaxExtraField; ?>&a=get_second_select_options",
dataType: "json",
data: "type=session&field_id="+field_id+"&option_value_id="+id,
success: function(data) {
my_select = second_filters[field_id];
my_select.empty();
$.each(data, function(index, value) {
my_select.append($("<option/>", {
value: index,
text: value
}));
});
}
});
});
}
<?php
echo Display::grid_js(
'sessions',
$url,
$columns,
$columnModel,
$extraParams,
[],
null,
true
);
?>
setSearchSelect("status");
var grid = $("#sessions"),
prmSearch = {
multipleSearch : true,
overlay : false,
width: 'auto',
caption: '<?php echo addslashes(get_lang('Search')); ?>',
formclass:'data_table',
onSearch : function() {
var postdata = grid.jqGrid('getGridParam', 'postData');
if (postdata && postdata.filters) {
filters = jQuery.parseJSON(postdata.filters);
clean_cols(grid, added_cols);
added_cols = [];
$.each(filters, function(key, value) {
if (key == 'rules') {
$.each(value, function(subkey, subvalue) {
added_cols[subvalue.field] = subvalue.field;
});
}
});
show_cols(grid, added_cols);
}
},
onReset: function() {
clean_cols(grid, added_cols);
}
};
original_cols = grid.jqGrid('getGridParam', 'colModel');
grid.jqGrid('navGrid','#sessions_pager',
{edit:false,add:false,del:false},
{height:280,reloadAfterSubmit:false}, // edit options
{height:280,reloadAfterSubmit:false}, // add options
{reloadAfterSubmit:false},// del options
prmSearch
);
<?php
// Create the searching dialog.
//echo 'grid.searchGrid(prmSearch);';
?>
// Fixes search table.
var searchDialogAll = $("#fbox_"+grid[0].id);
searchDialogAll.addClass("table");
var searchDialog = $("#searchmodfbox_"+grid[0].id);
searchDialog.addClass("ui-jqgrid ui-widget ui-widget-content ui-corner-all");
searchDialog.css({position:"adsolute", "z-index":"100", "float":"left", "top":"55%", "left" : "25%", "padding" : "5px", "border": "1px solid #CCC"})
var gbox = $("#gbox_"+grid[0].id);
gbox.before(searchDialog);
gbox.css({clear:"left"});
// Select first elements by default
$('.input-elm').each(function() {
$(this).find('option:first').attr('selected', 'selected');
});
$('.delete-rule').each(function(){
$(this).click(function(){
$('.input-elm').each(function(){
$(this).find('option:first').attr('selected', 'selected');
});
});
});
});
</script>
<?php
$form->display();
echo Display::grid_html('session_tracking');
echo Display::grid_html('sessions');
Display::display_footer();

@ -38,10 +38,12 @@ foreach ($sessionList as $sessionInfo) {
$selectSession->addOption($sessionInfo['name'], $sessionInfo['id']);
}
if (isset($_GET['session']) && intval($_GET['session'])) {
$form->setDefaults(['session' => intval($_GET['session'])]);
$sessionId = isset($_GET['session']) ? (int) $_GET['session'] : 0;
$session = null;
if (!empty($sessionId)) {
$form->setDefaults(['session' => $sessionId]);
/** @var Session $session */
$session = $em->find('ChamiloCoreBundle:Session', intval($_GET['session']));
$session = $em->find('ChamiloCoreBundle:Session', $sessionId);
}
$coursesInfo = [];

@ -6,8 +6,6 @@
*
* @todo use formvalidator
*/
// resetting the course id.
$cidReset = true;
require_once __DIR__.'/../inc/global.inc.php';
@ -29,7 +27,7 @@ $interbreadcrumb[] = [
'name' => get_lang('SessionList'),
];
$interbreadcrumb[] = [
'url' => "resume_session.php?id_session=".$sessionId,
'url' => "resume_session.php?id_session=$sessionId",
'name' => get_lang('SessionOverview'),
];
@ -85,29 +83,32 @@ $courses = $sessions = [];
if (isset($_POST['formSent']) && $_POST['formSent']) {
$courseList = $_POST['SessionCoursesList'];
$copyEvaluation = isset($_POST['copy_evaluation']);
$copyCourseTeachersAsCoach = isset($_POST['import_teachers_as_course_coach']);
SessionManager::add_courses_to_session(
$sessionId,
$courseList,
true,
$copyEvaluation
$copyEvaluation,
$copyCourseTeachersAsCoach
);
Display::addFlash(Display::return_message(get_lang('Updated')));
$url = api_get_path(WEB_CODE_PATH).'session/';
if (isset($add)) {
header('Location: add_users_to_session.php?id_session='.$sessionId.'&add=true');
header('Location: '.$url.'add_users_to_session.php?id_session='.$sessionId.'&add=true');
} else {
header('Location: resume_session.php?id_session='.$sessionId);
header('Location: '.$url.'resume_session.php?id_session='.$sessionId);
}
exit;
}
// display the header
// Display the header
Display::display_header($tool_name);
if ($add_type == 'multiple') {
if ($add_type === 'multiple') {
$link_add_type_unique = '<a href="'.api_get_self().'?id_session='.$sessionId.'&add='.$add.'&add_type=unique">'.
Display::return_icon('single.gif').get_lang('SessionAddTypeUnique').'</a>';
$link_add_type_multiple = Display::return_icon('multiple.gif').get_lang('SessionAddTypeMultiple').' ';
@ -123,7 +124,7 @@ echo '<div class="actions">';
echo $link_add_type_unique.$link_add_type_multiple;
echo '</div>';
$ajax_search = $add_type == 'unique' ? true : false;
$ajax_search = $add_type === 'unique' ? true : false;
$nosessionCourses = $sessionCourses = [];
if ($ajax_search) {
$sql = "SELECT course.id, code, title, visual_code, session_id
@ -131,8 +132,8 @@ if ($ajax_search) {
INNER JOIN $tbl_session_rel_course session_rel_course
ON
course.id = session_rel_course.c_id AND
session_rel_course.session_id = ".$sessionId."
ORDER BY ".(sizeof($courses) ? "(code IN(".implode(',', $courses).")) DESC," : "")." title";
session_rel_course.session_id = $sessionId
ORDER BY ".(count($courses) ? "(code IN (".implode(',', $courses).")) DESC," : '')." title";
if (api_is_multiple_url_enabled()) {
$tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
@ -141,12 +142,11 @@ if ($ajax_search) {
$sql = "SELECT course.id, code, title, visual_code, session_id
FROM $tbl_course course
INNER JOIN $tbl_session_rel_course session_rel_course
ON course.id = session_rel_course.c_id
AND session_rel_course.session_id = ".$sessionId."
INNER JOIN $tbl_course_rel_access_url url_course
ON (url_course.c_id = course.id)
ON course.id = session_rel_course.c_id AND session_rel_course.session_id = $sessionId
INNER JOIN $tbl_course_rel_access_url url_course
ON (url_course.c_id = course.id)
WHERE access_url_id = $access_url_id
ORDER BY ".(sizeof($courses) ? "(code IN(".implode(',', $courses).")) DESC," : "")." title";
ORDER BY ".(count($courses) ? " (code IN(".implode(',', $courses).")) DESC," : '')." title";
}
}
@ -161,8 +161,8 @@ if ($ajax_search) {
LEFT JOIN $tbl_session_rel_course session_rel_course
ON
course.id = session_rel_course.c_id AND
session_rel_course.session_id = ".$sessionId."
ORDER BY ".(sizeof($courses) ? "(code IN(".implode(',', $courses).")) DESC," : "")." title";
session_rel_course.session_id = $sessionId
ORDER BY ".(count($courses) ? "(code IN(".implode(',', $courses).")) DESC," : '')." title";
if (api_is_multiple_url_enabled()) {
$tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
@ -173,11 +173,11 @@ if ($ajax_search) {
LEFT JOIN $tbl_session_rel_course session_rel_course
ON
course.id = session_rel_course.c_id AND
session_rel_course.session_id = ".$sessionId."
session_rel_course.session_id = $sessionId
INNER JOIN $tbl_course_rel_access_url url_course
ON (url_course.c_id = course.id)
WHERE access_url_id = $access_url_id
ORDER BY ".(sizeof($courses) ? "(code IN(".implode(',', $courses).")) DESC," : "")." title";
ORDER BY ".(count($courses) ? "(code IN(".implode(',', $courses).")) DESC," : '')." title";
}
}
$result = Database::query($sql);
@ -208,7 +208,8 @@ if (!api_is_platform_admin() && api_is_teacher()) {
unset($Courses);
?>
<form name="formulaire" method="post" action="<?php echo api_get_self(); ?>?page=<?php echo $page; ?>&id_session=<?php echo $sessionId; ?><?php if (!empty($_GET['add'])) {
<form name="formulaire"
method="post" action="<?php echo api_get_self(); ?>?page=<?php echo $page; ?>&id_session=<?php echo $sessionId; if (!empty($_GET['add'])) {
echo '&add=true';
} ?>" style="margin:0px;" <?php if ($ajax_search) {
echo ' onsubmit="valide();"';
@ -251,7 +252,7 @@ unset($Courses);
<div class="code-course">
<?php echo get_lang('FirstLetterCourse'); ?> :
<select name="firstLetterCourse" onchange = "xajax_search_courses(this.value,'multiple', <?php echo $sessionId; ?>)" class="selectpicker show-tick form-control">
<select name="firstLetterCourse" onchange = "xajax_search_courses(this.value,'multiple', <?php echo $sessionId; ?>)" class="selectpicker form-control">
<option value="%">--</option>
<?php
echo Display :: get_alphabet_options();
@ -289,6 +290,10 @@ unset($Courses);
<input type="checkbox" name="copy_evaluation">
<?php echo get_lang('ImportGradebookInCourse'); ?>
</label>
<label>
<input type="checkbox" name="import_teachers_as_course_coach">
<?php echo get_lang('ImportCourseTeachersAsCourseCoach'); ?>
</label>
</div>
<?php
echo '<div class="separate-action">';
@ -304,7 +309,6 @@ unset($Courses);
<div class="col-md-4">
<label><?php echo get_lang('CourseListInSession'); ?> :</label>
<select id='destination' name="SessionCoursesList[]" multiple="multiple" size="20" class="form-control">
<?php
foreach ($sessionCourses as $enreg) {
?>
@ -347,10 +351,10 @@ unset($Courses);
}
function mysort(a, b) {
if(a.text.toLowerCase() > b.text.toLowerCase()){
if (a.text.toLowerCase() > b.text.toLowerCase()){
return 1;
}
if(a.text.toLowerCase() < b.text.toLowerCase()){
if (a.text.toLowerCase() < b.text.toLowerCase()){
return -1;
}
return 0;

@ -7,7 +7,6 @@
// resetting the course id
$cidReset = true;
// including some necessary files
require_once __DIR__.'/../inc/global.inc.php';
$xajax = new xajax();
$xajax->registerFunction('search_users');
@ -43,7 +42,6 @@ if (isset($_REQUEST['add_type']) && $_REQUEST['add_type'] != '') {
$page = isset($_GET['page']) ? Security::remove_XSS($_GET['page']) : null;
// Checking for extra field with filter on
$extra_field_list = UserManager::get_extra_fields();
$new_field_list = [];
@ -108,7 +106,7 @@ function search_users($needle, $type)
// Only for single & multiple
if (in_array($type, ['single', 'multiple'])) {
if (!empty($id_session)) {
$id_session = intval($id_session);
$id_session = (int) $id_session;
// check id_user from session_rel_user table
$sql = "
SELECT user_id FROM $tbl_session_rel_user
@ -180,14 +178,14 @@ function search_users($needle, $type)
INNER JOIN $tbl_user_rel_access_url url_user
ON (url_user.user_id = user.id)
WHERE
access_url_id = '$access_url_id'
AND (
username LIKE '$needle%'
OR lastname LIKE '$needle%'
OR firstname LIKE '$needle%'
)
AND user.status <> 6
AND user.status <> ".DRH."
access_url_id = '$access_url_id' AND
(
username LIKE '$needle%' OR
lastname LIKE '$needle%' OR
firstname LIKE '$needle%'
) AND
user.status <> 6 AND
user.status <> ".DRH."
$order_clause LIMIT 11
";
break;
@ -238,8 +236,11 @@ function search_users($needle, $type)
$officialCode.$user['lastname'].' '.$user['firstname'].' ('.$user['username'].')';
}
$return .= '<a href="javascript: void(0);" onclick="javascript: add_user_to_session(\''.$user['id']
.'\',\''.$person_name.' '.'\')">'.$person_name.' </a><br />';
$return .= Display::url(
$person_name,
'javascript: void(0);',
['onclick' => "add_user_to_session('".$user['id']."', '".addslashes($person_name)."');"]
).'<br>';
} else {
$return .= '...<br />';
}
@ -247,7 +248,6 @@ function search_users($needle, $type)
$xajax_response->addAssign('ajax_list_users_single', 'innerHTML', api_utf8_encode($return));
} else {
global $nosessionUsersList;
$return .= '<select id="origin_users" name="nosessionUsersList[]" multiple="multiple" size="15" style="width:360px;">';
while ($user = Database:: fetch_array($rs)) {
$person_name =

@ -104,7 +104,7 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
<div class="actions">
<div class="row">
<div class="col-md-6">
<?php
<?php
echo Display::url(
Display::return_icon('new_folder.png', get_lang('AddSessionCategory'), [], ICON_SIZE_MEDIUM),
api_get_path(WEB_CODE_PATH).'session/session_category_add.php'
@ -116,16 +116,16 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
</div>
<div class="col-md-6">
<div class="pull-right">
<form method="POST" action="session_category_list.php" class="form-inline">
<div class="form-group">
<input class="form-control" type="text" name="keyword" value="<?php echo $keyword; ?>"
aria-label="<?php echo get_lang('Search'); ?>"/>
<form method="POST" action="session_category_list.php" class="form-inline">
<div class="form-group">
<input class="form-control" type="text" name="keyword" value="<?php echo $keyword; ?>"
aria-label="<?php echo get_lang('Search'); ?>"/>
<button class="btn btn-default" type="submit" name="name"
value="<?php echo get_lang('Search'); ?>"><em
class="fa fa-search"></em> <?php echo get_lang('Search'); ?></button>
<!-- <a href="session_list.php?search=advanced"><?php echo get_lang('AdvancedSearch'); ?></a> -->
</div>
</form>
<!-- <a href="session_list.php?search=advanced"><?php echo get_lang('AdvancedSearch'); ?></a> -->
</div>
</form>
</div>
</div>
</div>
@ -140,39 +140,39 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
?>
<div>
<?php
if ($page) {
?>
if ($page) {
?>
<a href="<?php echo api_get_self(); ?>?page=<?php echo $page
- 1; ?>&sort=<?php echo $sort; ?>&order=<?php echo Security::remove_XSS(
$order
); ?>&keyword=<?php echo $keyword; ?><?php echo @$cond_url; ?>"><?php echo get_lang(
'Previous'
); ?></a>
<?php
} else {
echo get_lang('Previous');
} ?>
|
<?php
} else {
echo get_lang('Previous');
} ?>
|
<?php
if ($nbr_results > $limit) {
?>
if ($nbr_results > $limit) {
?>
<a href="<?php echo api_get_self(); ?>?page=<?php echo $page
+ 1; ?>&sort=<?php echo $sort; ?>&order=<?php echo Security::remove_XSS(
$order
); ?>&keyword=<?php echo $keyword; ?><?php echo @$cond_url; ?>"><?php echo get_lang(
'Next'
); ?></a>
<?php
} else {
echo get_lang('Next');
} ?>
</div>
<?php
} else {
echo get_lang('Next');
} ?>
</div>
<?php
} ?>
<table class="data_table" width="100%">
<tr>
<th>&nbsp;</th>
<tr>
<th>&nbsp;</th>
<th><a href="<?php echo api_get_self(); ?>?sort=name&order=<?php echo ($sort == 'name') ? $order
: 'ASC'; ?>"><?php echo get_lang('SessionCategoryName'); ?></a></th>
<th><a href="<?php echo api_get_self(); ?>?sort=nbr_session&order=<?php echo ($sort
@ -181,11 +181,11 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
? $order : 'ASC'; ?>"><?php echo get_lang('StartDate'); ?></a></th>
<th><a href="<?php echo api_get_self(); ?>?sort=date_end&order=<?php echo ($sort == 'date_end')
? $order : 'ASC'; ?>"><?php echo get_lang('EndDate'); ?></a></th>
<th><?php echo get_lang('Actions'); ?></th>
</tr>
<th><?php echo get_lang('Actions'); ?></th>
</tr>
<?php
$i = 0;
<?php
$i = 0;
$x = 0;
foreach ($Sessions as $key => $enreg) {
if ($key == $limit) {
@ -201,103 +201,103 @@ if (isset($_GET['search']) && $_GET['search'] === 'advanced') {
$rs = Database::query($sql);
list($nb_courses) = Database::fetch_array($rs); ?>
<tr class="<?php echo $i ? 'row_odd' : 'row_even'; ?>">
<tr class="<?php echo $i ? 'row_odd' : 'row_even'; ?>">
<td><input type="checkbox" id="idChecked_<?php echo $x; ?>" name="idChecked[]"
value="<?php echo $enreg['id']; ?>"></td>
<td><?php echo api_htmlentities($enreg['name'], ENT_QUOTES, $charset); ?></td>
<td><?php echo api_htmlentities($enreg['name'], ENT_QUOTES, $charset); ?></td>
<td><?php echo "<a href=\"session_list.php?id_category=".$enreg['id']."\">".$nb_courses
." Session(s) </a>"; ?></td>
<td><?php echo api_format_date($enreg['date_start'], DATE_FORMAT_SHORT); ?></td>
<td>
<?php
if (!empty($enreg['date_end']) && $enreg['date_end'] != '0000-00-00') {
echo api_format_date($enreg['date_end'], DATE_FORMAT_SHORT);
} else {
echo '-';
} ?>
</td>
<td>
<a href="session_category_edit.php?&id=<?php echo $enreg['id']; ?>">
<?php Display::display_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL); ?>
</a>
<td><?php echo api_format_date($enreg['date_start'], DATE_FORMAT_SHORT); ?></td>
<td>
<?php
if (!empty($enreg['date_end']) && $enreg['date_end'] != '0000-00-00') {
echo api_format_date($enreg['date_end'], DATE_FORMAT_SHORT);
} else {
echo '-';
} ?>
</td>
<td>
<a href="session_category_edit.php?&id=<?php echo $enreg['id']; ?>">
<?php Display::display_icon('edit.png', get_lang('Edit'), [], ICON_SIZE_SMALL); ?>
</a>
<a href="<?php echo api_get_self(
); ?>?sort=<?php echo $sort; ?>&action=delete_off_session&idChecked=<?php echo $enreg['id']; ?>"
onclick="if(!confirm('<?php echo get_lang(
'ConfirmYourChoice'
); ?>')) return false;">
<?php Display::display_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL); ?>
</a>
</td>
</tr>
<?php
$i = $i ? 0 : 1;
<?php Display::display_icon('delete.png', get_lang('Delete'), [], ICON_SIZE_SMALL); ?>
</a>
</td>
</tr>
<?php
$i = $i ? 0 : 1;
$x++;
}
unset($Sessions); ?>
</table>
<br />
</table>
<br/>
<div>
<?php
if ($num > $limit) {
if ($page) {
?>
<?php
if ($num > $limit) {
if ($page) {
?>
<a href="<?php echo api_get_self(); ?>?page=<?php echo $page
- 1; ?>&sort=<?php echo $sort; ?>&order=<?php echo Security::remove_XSS(
$_REQUEST['order']
); ?>&keyword=<?php echo $_REQUEST['keyword']; ?><?php echo @$cond_url; ?>">
<?php echo get_lang('Previous'); ?></a>
<?php
} else {
echo get_lang('Previous');
} ?>
|
<?php
if ($nbr_results > $limit) {
?>
<?php echo get_lang('Previous'); ?></a>
<?php
} else {
echo get_lang('Previous');
} ?>
|
<?php
if ($nbr_results > $limit) {
?>
<a href="<?php echo api_get_self(); ?>?page=<?php echo $page
+ 1; ?>&sort=<?php echo $sort; ?>&order=<?php echo Security::remove_XSS(
$_REQUEST['order']
); ?>&keyword=<?php echo $_REQUEST['keyword']; ?><?php echo @$cond_url; ?>">
<?php echo get_lang('Next'); ?></a>
<?php echo get_lang('Next'); ?></a>
<?php
} else {
echo get_lang('Next');
}
} ?>
</div>
<?php
} else {
echo get_lang('Next');
}
} ?>
</div>
<div class="row">
<div class="col-sm-4">
<div class="btn-group">
<div class="btn-group">
<button type="button" class="btn btn-default" onclick="selectAll('idChecked',<?php echo $x; ?>,'true');">
<?php echo get_lang('SelectAll'); ?>
</button>
<button type="button" class="btn btn-default" onclick="selectAll('idChecked',<?php echo $x; ?>,'false');">
<?php echo get_lang('UnSelectAll'); ?>
</button>
</div>
</div>
</div>
<div class="col-sm-6">
<select class="selectpicker show-tick form-control" name="action">
<select class="selectpicker form-control" name="action">
<option value="delete_off_session" selected="selected">
<?php echo get_lang('DeleteSelectedSessionCategory'); ?>
</option>
<option value="delete_on_session">
<?php echo get_lang('DeleteSelectedFullSessionCategory'); ?>
</option>
</select>
</div>
</select>
</div>
<div class="col-sm-2">
<button class="btn btn-success" type="submit" name="name" value="<?php echo get_lang('Ok'); ?>">
<?php echo get_lang('Ok'); ?>
</button>
</div>
</div>
<?php
<?php
} ?>
</table>
</table>
</form>
<?php
<?php
}
Display::display_footer();

@ -136,13 +136,8 @@ $extra_params['height'] = 'auto';
if (!isset($_GET['keyword'])) {
$extra_params['postData'] = [
'filters' => [
"groupOp" => "AND",
"rules" => $result['rules'],
/*array(
array( "field" => "display_start_date", "op" => "gt", "data" => ""),
array( "field" => "display_end_date", "op" => "gt", "data" => "")
),*/
//'groups' => $groups
'groupOp' => 'AND',
'rules' => $result['rules'],
],
];
}
@ -167,23 +162,14 @@ $orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
<script>
function setSearchSelect(columnName) {
$("#sessions").jqGrid('setColProp', columnName, {
/*searchoptions:{
dataInit:function(el){
$("option[value='1']",el).attr("selected", "selected");
setTimeout(function(){
$(el).trigger('change');
}, 1000);
}
}*/
});
}
var added_cols = [];
var original_cols = [];
function clean_cols(grid, added_cols) {
//Cleaning
// Cleaning
for (key in added_cols) {
//console.log('hide: ' + key);
grid.hideCol(key);
};
grid.showCol('name');
@ -195,7 +181,6 @@ $orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
function show_cols(grid, added_cols) {
grid.showCol('name').trigger('reloadGrid');
for (key in added_cols) {
//console.log('show: ' + key);
grid.showCol(key);
};
}
@ -271,17 +256,12 @@ $orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
filters = jQuery.parseJSON(postdata.filters);
clean_cols(grid, added_cols);
added_cols = [];
$.each(filters, function(key, value){
//console.log('key: ' + key );
$.each(filters, function(key, value) {
if (key == 'rules') {
$.each(value, function(subkey, subvalue) {
if (subvalue.data == undefined) {
}
//if (added_cols[value.field] == undefined) {
added_cols[subvalue.field] = subvalue.field;
//}
//grid.showCol(value.field);
});
}
});
@ -311,10 +291,10 @@ $orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
});
orderList = JSON.stringify(orderList);
$.get("<?php echo $orderUrl; ?>", "order="+orderList, function (result) {
//console.log(result);
});
}
};
// Sortable rows
grid.jqGrid('sortableRows', options);
<?php
@ -345,7 +325,7 @@ $orderUrl = api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=order';
gbox.before(searchDialog);
gbox.css({clear:"left"});
//Select first elements by default
// Select first elements by default
$('.input-elm').each(function(){
$(this).find('option:first').attr('selected', 'selected');
});

@ -0,0 +1,30 @@
<?php
/* For licensing terms, see /license.txt */
require_once __DIR__.'/../inc/global.inc.php';
$userId = isset($_GET['user_id']) ? (int) $_GET['user_id'] : 0;
$file = isset($_GET['file']) ? $_GET['file'] : '';
if (empty($userId) || empty($file)) {
exit;
}
$dir = UserManager::getUserPathById($userId, 'system');
if (empty($dir)) {
exit;
}
$file = $dir.'/my_files/'.$file;
$config = api_get_configuration_value('block_my_files_access');
if ($config) {
api_block_anonymous_users();
}
if (Security::check_abs_path($file, $dir.'my_files/')) {
$result = DocumentManager::file_send_for_download($file);
if ($result === false) {
exit;
}
}

@ -88,6 +88,9 @@ $formSearch->addText(
]
);
// Added a Jquery Function to return the Preview of OpenGraph URL Content
$htmlHeadXtra[] = SocialManager::getScriptToGetOpenGraph();
$tpl = new Template(get_lang('SocialNetwork'));
SocialManager::setSocialUserBlock($tpl, $user_id, 'home');
$tpl->assign('social_wall_block', $wallSocialAddPost);
@ -97,7 +100,7 @@ $tpl->assign('social_auto_extend_link', $socialAutoExtendLink);
$tpl->assign('search_friends_form', $formSearch->returnForm());
$tpl->assign('social_friend_block', $friend_html);
$tpl->assign('social_search_block', $social_search_block);
$tpl->assign('social_skill_block', SocialManager::getSkillBlock($user_id));
$tpl->assign('social_skill_block', SocialManager::getSkillBlock($user_id, 'vertical'));
$tpl->assign('social_group_block', $social_group_block);
$tpl->assign('session_list', $social_session_block);
$social_layout = $tpl->get_template('social/home.tpl');

@ -28,6 +28,12 @@ switch ($action) {
$certificate = new Certificate(0, api_get_user_id(), false, false);
$certificate->generatePdfFromCustomCertificate();
break;
case 'generate':
$certificate = Certificate::generateUserSkills(api_get_user_id());
Display::addFlash(Display::return_message(get_lang('Updated')));
header('Location: '.api_get_self());
exit;
break;
}
$skillTable = Database::get_main_table(TABLE_MAIN_SKILL);

Loading…
Cancel
Save