Add security fixes from 1.11.x

pull/3890/head
Julio Montoya 4 years ago
parent 0cadc19907
commit a707bace33
  1. 66
      public/main/inc/ajax/exercise.ajax.php
  2. 227
      public/main/inc/ajax/model.ajax.php
  3. 2
      public/main/inc/lib/TicketManager.php
  4. 16
      public/main/inc/lib/api.lib.php
  5. 24
      public/main/inc/lib/course.lib.php
  6. 6
      public/main/inc/lib/database.lib.php
  7. 4
      public/main/inc/lib/display.lib.php
  8. 3
      public/main/inc/lib/exercise.lib.php
  9. 8
      public/main/inc/lib/extra_field.lib.php
  10. 18
      public/main/inc/lib/fileUpload.lib.php
  11. 2
      public/main/inc/lib/security.lib.php
  12. 6
      public/main/inc/lib/zombie/zombie_manager.class.php

@ -139,7 +139,6 @@ switch ($action) {
$em->persist($attempt);
$em->flush();
echo 1;
}
} else {
if ($debug) {
@ -239,7 +238,7 @@ switch ($action) {
GROUP BY exe_user_id
) as aa
ON aa.exe_user_id = u.id
ORDER BY $sidx $sord
ORDER BY `$sidx` $sord
LIMIT $start, $limit";
$result = Database::query($sql);
@ -413,12 +412,13 @@ switch ($action) {
echo $objExercise->getReminderTable($questionList, $statInfo, true);
break;
case 'save_exercise_by_now':
header('Content-Type: application/json');
$course_info = api_get_course_info_by_id($course_id);
$course_id = $course_info['real_id'];
// Use have permissions to edit exercises results now?
if (false === api_is_allowed_to_session_edit()) {
echo 'error';
echo json_encode(['error' => true]);
if ($debug) {
error_log(
'Exercises attempt '.$exeId.': Failed saving question(s) in course/session '.
@ -468,7 +468,7 @@ switch ($action) {
// If exercise or question is not set then exit.
if (empty($question_list) || empty($objExercise)) {
echo 'error';
echo json_encode(['error' => true]);
if ($debug) {
if (empty($question_list)) {
error_log('question_list is empty');
@ -481,12 +481,12 @@ switch ($action) {
}
if (WhispeakAuthPlugin::questionRequireAuthentify($question_id)) {
if (ONE_PER_PAGE == $objExercise->type) {
echo 'one_per_page';
if ($objExercise->type == ONE_PER_PAGE) {
echo json_encode(['type' => 'one_per_page']);
break;
}
echo 'ok';
echo json_encode(['ok' => true]);
break;
} else {
ChamiloSession::erase(WhispeakAuthPlugin::SESSION_QUIZ_QUESTION);
@ -510,7 +510,7 @@ switch ($action) {
// No exe id? Can't save answer.
if (empty($exeId)) {
// Fires an error.
echo 'error';
echo json_encode(['error' => true]);
if ($debug) {
error_log('exe_id is empty');
}
@ -554,9 +554,10 @@ switch ($action) {
error_log('Starting questions loop in save_exercise_by_now');
}
$now = time();
if ('all' === $type) {
// Check we have at least one non-empty answer in the array
// provided by the user's click on the "Finish test" button.
if ('all' === $type) {
$atLeastOneAnswer = false;
foreach ($question_list as $my_question_id) {
if (!empty($choice[$my_question_id])) {
@ -565,13 +566,30 @@ switch ($action) {
}
}
if (!$atLeastOneAnswer) {
// Check if time is over.
if ($objExercise->expired_time != 0) {
$clockExpiredTime = ExerciseLib::get_session_time_control_key(
$objExercise->id,
$learnpath_id,
$learnpath_item_id
);
if (!empty($clockExpiredTime)) {
$timeLeft = api_strtotime($clockExpiredTime, 'UTC') - $now;
if ($timeLeft <= 0) {
// There's no time, but still no answers ...
echo json_encode(['ok' => true, 'savedAnswerMessage' => '']);
exit;
}
}
}
error_log(
'In '.__FILE__.'::action save_exercise_by_now,'.
' from user '.api_get_user_id().
' for track_e_exercises.exe_id = '.$exeId.
', we received an empty set of answers.'.
'Preventing submission to avoid overwriting w/ null.');
echo 'error';
'Preventing submission to avoid overwriting w/ null.'
);
echo json_encode(['error' => true]);
exit;
}
}
@ -642,7 +660,7 @@ switch ($action) {
if (!empty($value) && isset($value['value']) && !empty($value['value'])) {
$questionDuration = Event::getAttemptQuestionDuration($exeId, $objQuestionTmp->iid);
if (empty($questionDuration)) {
echo 'error';
echo json_encode(['error' => true]);
if ($debug) {
error_log("Question duration = 0, in exeId: $exeId, question_id: $my_question_id");
}
@ -728,7 +746,6 @@ switch ($action) {
}
$duration = 0;
$now = time();
if ('all' == $type) {
$exercise_stat_info = $objExercise->get_stat_track_exercise_info_by_exe_id($exeId);
}
@ -810,12 +827,27 @@ switch ($action) {
if ($debug) {
error_log('Finished questions loop in save_exercise_by_now');
}
if ('all' === $type) {
$questionsCount = count(explode(',', $exercise_stat_info['data_tracking']));
$savedAnswersCount = $objExercise->countUserAnswersSavedInExercise($exeId);
if ($savedAnswersCount !== $questionsCount) {
$savedQuestionsMessage = Display::span(
sprintf(get_lang('XAnswersSavedByUsersFromXTotal'), $savedAnswersCount, $questionsCount),
['class' => 'text-warning']
);
} else {
$savedQuestionsMessage = Display::span(
sprintf(get_lang('XAnswersSavedByUsersFromXTotal'), $savedAnswersCount, $questionsCount),
['class' => 'text-success']
);
}
if ($type === 'all') {
if ($debug) {
error_log("result: ok - all");
error_log(" ------ end ajax call ------- ");
}
echo 'ok';
echo json_encode(['ok' => true, 'savedAnswerMessage' => $savedQuestionsMessage]);
exit;
}
@ -824,14 +856,14 @@ switch ($action) {
error_log('result: one_per_page');
error_log(' ------ end ajax call ------- ');
}
echo 'one_per_page';
echo json_encode(['type' => 'one_per_page', 'savedAnswerMessage' => $savedQuestionsMessage]);
exit;
}
if ($debug) {
error_log('result: ok');
error_log(' ------ end ajax call ------- ');
}
echo 'ok';
echo json_encode(['ok' => true, 'savedAnswerMessage' => $savedQuestionsMessage]);
break;
case 'show_question':
$isAllowedToEdit = api_is_allowed_to_edit(null, true, false, false);

@ -45,6 +45,7 @@ if (!in_array(
$action,
[
'get_exercise_results',
'get_exercise_pending_results',
'get_exercise_results_report',
'get_work_student_list_overview',
'get_work_teacher',
@ -112,13 +113,13 @@ function getWhereClause($col, $oper, $val)
return '';
}
if ('bw' == $oper || 'bn' == $oper) {
if ($oper == 'bw' || $oper == 'bn') {
$val .= '%';
}
if ('ew' == $oper || 'en' == $oper) {
if ($oper == 'ew' || $oper == 'en') {
$val = '%'.$val;
}
if ('cn' == $oper || 'nc' == $oper || 'in' == $oper || 'ni' == $oper) {
if ($oper == 'cn' || $oper == 'nc' || $oper == 'in' || $oper == 'ni') {
$val = '%'.$val.'%';
}
$val = Database::escape_string($val);
@ -156,13 +157,16 @@ if (($search || $forceSearch) && ('false' !== $search)) {
$whereCondition .= ' AND ( ';
$whereCondition .= ' ('.$whereConditionInForm.') ';
}
$filters = isset($_REQUEST['filters']) && !is_array($_REQUEST['filters']) ? json_decode($_REQUEST['filters']) : false;
$filters = isset($_REQUEST['filters']) && !is_array($_REQUEST['filters']) ? json_decode(
$_REQUEST['filters']
) : false;
if (isset($_REQUEST['filters2'])) {
$filters = json_decode($_REQUEST['filters2']);
}
if (!empty($filters)) {
if (in_array($action,
if (in_array(
$action,
[
'get_user_course_report_resumed',
'get_user_course_report',
@ -543,14 +547,14 @@ switch ($action) {
$count = AnnouncementManager::getNumberAnnouncements();
break;
case 'get_work_teacher':
$count = getWorkListTeacher(0, $limit, $sidx, $sord, $whereCondition, true);
$count = getWorkListTeacher(0, $limit, null, null, $whereCondition, true);
break;
case 'get_work_student':
$count = getWorkListStudent(0, $limit, $sidx, $sord, $whereCondition, true);
$count = getWorkListStudent(0, $limit, null, null, $whereCondition, true);
break;
case 'get_all_work_student':
$withResults = isset($_REQUEST['with_results']) ? (int) $_REQUEST['with_results'] : 0;
$count = getAllWorkListStudent(0, $limit, $sidx, $sord, $whereCondition, true, $withResults);
$count = getAllWorkListStudent(0, $limit, null, null, $whereCondition, true, $withResults);
break;
case 'get_work_user_list_all':
$work_id = $_REQUEST['work_id'];
@ -588,8 +592,8 @@ switch ($action) {
$count = get_work_user_list(
0,
$limit,
$sidx,
$sord,
null,
null,
$work_id,
$whereCondition,
null,
@ -599,8 +603,8 @@ switch ($action) {
$count = get_work_user_list_from_documents(
0,
$limit,
$sidx,
$sord,
null,
null,
$work_id,
api_get_user_id(),
$whereCondition,
@ -624,10 +628,59 @@ switch ($action) {
null,
true
);
break;
case 'get_exercise_pending_results':
if (false === api_is_teacher()) {
exit;
}
$courseId = $_REQUEST['course_id'] ?? 0;
$exerciseId = $_REQUEST['exercise_id'] ?? 0;
$status = $_REQUEST['status'] ?? 0;
if (isset($_GET['filter_by_user']) && !empty($_GET['filter_by_user'])) {
$filter_user = (int) $_GET['filter_by_user'];
if (empty($whereCondition)) {
$whereCondition .= " te.exe_user_id = '$filter_user'";
} else {
$whereCondition .= " AND te.exe_user_id = '$filter_user'";
}
}
if (isset($_GET['group_id_in_toolbar']) && !empty($_GET['group_id_in_toolbar'])) {
$groupIdFromToolbar = (int) $_GET['group_id_in_toolbar'];
if (!empty($groupIdFromToolbar)) {
if (empty($whereCondition)) {
$whereCondition .= " te.group_id = '$groupIdFromToolbar'";
} else {
$whereCondition .= " AND group_id = '$groupIdFromToolbar'";
}
}
}
if (!empty($whereCondition)) {
$whereCondition = " AND $whereCondition";
}
if (!empty($courseId)) {
$whereCondition .= " AND te.c_id = $courseId";
}
$count = ExerciseLib::get_count_exam_results(
$exerciseId,
$whereCondition,
'',
false,
true,
$status
);
break;
case 'get_exercise_results':
$exercise_id = $_REQUEST['exerciseId'];
$courseId = $_REQUEST['course_id'] ?? 0;
$exerciseId = $_REQUEST['exercise_id'] ?? 0;
$status = $_REQUEST['status'] ?? 0;
if (isset($_GET['filter_by_user']) && !empty($_GET['filter_by_user'])) {
$filter_user = (int) $_GET['filter_by_user'];
if (empty($whereCondition)) {
@ -879,29 +932,36 @@ switch ($action) {
$keyword = isset($_REQUEST['keyword']) ? $_REQUEST['keyword'] : '';
$course_id = api_get_course_int_id();
$sessionId = api_get_session_id();
$options = [];
$options['course_id'] = $course_id;
$options['session_id'] = api_get_session_id();
$options['session_id'] = $sessionId;
switch ($type) {
case 'not_registered':
if (empty($sessionId)) {
$options['where'] = [' (course_id IS NULL OR course_id != ?) ' => $course_id];
} else {
$options['where'] = [' (session_id IS NULL OR session_id != ?) ' => $sessionId];
}
if (!empty($keyword)) {
$options['where']['AND name like %?% '] = $keyword;
}
$count = $obj->getUserGroupNotInCourse(
$options,
$groupFilter,
true,
true
);
break;
case 'registered':
if (empty($sessionId)) {
$options['where'] = [' usergroup.course_id = ? ' => $course_id];
} else {
$options['where'] = [' usergroup.session_id = ? ' => $sessionId];
}
$count = $obj->getUserGroupInCourse(
$options,
$groupFilter,
true,
true
);
break;
@ -983,6 +1043,7 @@ switch ($action) {
break;
case 'get_learning_path_calendars':
$columns = ['title', 'total_hours', 'minutes_per_day', 'actions'];
$sidx = in_array($sidx, $columns) ? $sidx : 'title';
$result = $calendarPlugin->getCalendars(
$start,
$limit,
@ -992,6 +1053,7 @@ switch ($action) {
break;
case 'course_log_events':
$columns = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
$sidx = in_array($sidx, $columns) ? $sidx : '0';
$result = Statistics::getActivitiesData(
$start,
$limit,
@ -1005,13 +1067,15 @@ switch ($action) {
$columns = ['subject', 'date', 'sent', 'actions'];
$sessionId = isset($_REQUEST['session_id']) ? (int) $_REQUEST['session_id'] : 0;
$sidx = in_array($sidx, $columns) ? $sidx : 'subject';
$result = Database::select(
'*',
$object->table,
[
'where' => ['session_id = ? ' => $sessionId],
'order' => "$sidx $sord",
'LIMIT' => "$start , $limit", ]
'LIMIT' => "$start , $limit",
]
);
if ($result) {
foreach ($result as &$item) {
@ -1022,6 +1086,7 @@ switch ($action) {
break;
case 'get_group_reporting':
$columns = ['name', 'time', 'progress', 'score', 'works', 'messages', 'actions'];
$sidx = in_array($sidx, $columns) ? $sidx : 'name';
$result = Tracking::get_group_reporting(
$course_id,
@ -1037,6 +1102,7 @@ switch ($action) {
break;
case 'get_course_exercise_medias':
$columns = ['question'];
$sidx = in_array($sidx, $columns) ? $sidx : 'question';
$result = Question::get_course_medias(
$course_id,
$start,
@ -1093,7 +1159,7 @@ switch ($action) {
null,
null,
"LIMIT $start, $limit",
null, //" $sidx $sord",
null,
null,
null,
true,
@ -1232,6 +1298,7 @@ switch ($action) {
if ('1 = 1' === trim($whereCondition)) {
$whereCondition = '';
}
$sidx = in_array($sidx, $columns) ? $sidx : 'firstname';
$result = $skill->getUserListSkillRanking(
$start,
$limit,
@ -1251,7 +1318,9 @@ switch ($action) {
$count_skill_by_course = [];
foreach ($personal_course_list as $course_item) {
if (!isset($skills_in_course[$course_item['code']])) {
$count_skill_by_course[$course_item['code']] = $skill->getCountSkillsByCourse($course_item['code']);
$count_skill_by_course[$course_item['code']] = $skill->getCountSkillsByCourse(
$course_item['code']
);
$skills_in_course[$course_item['code']] = $count_skill_by_course[$course_item['code']];
} else {
$count_skill_by_course[$course_item['code']] = $skills_in_course[$course_item['code']];
@ -1295,6 +1364,7 @@ switch ($action) {
'amount',
'actions',
];
$sidx = in_array($sidx, $columns) ? $sidx : 'title';
$result = getWorkListTeacher(
$start,
$limit,
@ -1312,6 +1382,7 @@ switch ($action) {
'last_upload',
'others',
];
$sidx = in_array($sidx, $columns) ? $sidx : 'title';
$result = getWorkListStudent(
$start,
$limit,
@ -1331,6 +1402,7 @@ switch ($action) {
$columns[] = 'feedback';
$columns[] = 'last_upload';
}
$sidx = in_array($sidx, $columns) ? $sidx : 'title';
$result = getAllWorkListStudent(
$start,
$limit,
@ -1371,6 +1443,7 @@ switch ($action) {
$whereCondition = " AND $whereCondition ";
$sidx = in_array($sidx, $columns) ? $sidx : 'title';
$result = get_work_user_list(
$start,
$limit,
@ -1401,6 +1474,7 @@ switch ($action) {
];
$columns = array_merge($columns, $plagiarismColumns);
$columns[] = 'actions';
$sidx = in_array($sidx, $columns) ? $sidx : 'work_name';
$result = getAllWork(
$start,
$limit,
@ -1420,7 +1494,13 @@ switch ($action) {
if (isset($_GET['type']) && 'simple' === $_GET['type']) {
$columns = [
'type', 'firstname', 'lastname', 'title', 'qualification', 'sent_date', 'qualificator_id',
'type',
'firstname',
'lastname',
'title',
'qualification',
'sent_date',
'qualificator_id',
];
$columns = array_merge($columns, $plagiarismColumns);
$columns[] = 'actions';
@ -1435,6 +1515,8 @@ switch ($action) {
}
$whereCondition .= " AND u.id <> ".api_get_user_id();
$sidx = in_array($sidx, $columns) ? $sidx : 'firstname';
$result = get_work_user_list(
$start,
$limit,
@ -1451,7 +1533,11 @@ switch ($action) {
}
if (isset($_GET['type']) && 'simple' == $_GET['type']) {
$columns = [
'type', 'title', 'qualification', 'sent_date', 'qualificator_id',
'type',
'title',
'qualification',
'sent_date',
'qualificator_id',
];
$columns = array_merge($columns, $plagiarismColumns);
$columns[] = 'actions';
@ -1466,6 +1552,7 @@ switch ($action) {
$whereCondition = '';
}
$sidx = in_array($sidx, $columns) ? $sidx : 'title';
if (empty($documents)) {
$whereCondition .= ' AND u.id = '.api_get_user_id();
$result = get_work_user_list(
@ -1487,6 +1574,48 @@ switch ($action) {
$whereCondition
);
}
break;
case 'get_exercise_pending_results':
$columns = [
'course',
'exercise',
'firstname',
'lastname',
'username',
'exe_duration',
'start_date',
'exe_date',
'score',
'user_ip',
'status',
'actions',
];
$officialCodeInList = api_get_setting('show_official_code_exercise_result_list');
if ($officialCodeInList === 'true') {
$columns = array_merge(['official_code'], $columns);
}
$sidx = in_array($sidx, $columns) ? $sidx : 'course';
$result = ExerciseLib::get_exam_results_data(
$start,
$limit,
$sidx,
$sord,
$exerciseId,
$whereCondition,
false,
null,
false,
false,
[],
false,
false,
false,
true,
$status
);
break;
case 'get_exercise_results':
$is_allowedToEdit = api_is_allowed_to_edit(null, true) ||
@ -1514,6 +1643,7 @@ switch ($action) {
}
}
$sidx = in_array($sidx, $columns) ? $sidx : 'firstname';
$result = ExerciseLib::get_exam_results_data(
$start,
$limit,
@ -1605,6 +1735,7 @@ switch ($action) {
$whereCondition .= " AND te.status = '' ";
$sidx = in_array($sidx, $columns) ? $sidx : 'firstname';
$result = ExerciseLib::get_exam_results_data(
$start,
$limit,
@ -1626,9 +1757,11 @@ switch ($action) {
return [];
}
$columns = [
'student', 'works',
'student',
'works',
];
$sidx = in_array($sidx, $columns) ? $sidx : 'student';
$result = getWorkUserListData(
$workId,
api_get_course_id(),
@ -1675,6 +1808,7 @@ switch ($action) {
['where' => $whereCondition, 'extra' => $extra_fields]
);
} else {
$sidx = in_array($sidx, $columns) ? $sidx : 'name';
// Sessions for the coach
$sessions = Tracking::get_sessions_coached_by_user(
api_get_user_id(),
@ -1772,6 +1906,7 @@ switch ($action) {
$sessionColumns = SessionManager::getGridColumns($listType);
$columns = $sessionColumns['simple_column_name'];
$sidx = in_array($sidx, $columns) ? $sidx : 'name';
switch ($listType) {
case 'complete':
$result = SessionManager::get_sessions_admin_complete(
@ -1823,6 +1958,7 @@ switch ($action) {
'answer',
'correct',
];
$sidx = in_array($sidx, $columns) ? $sidx : 'quiz_title';
$result = Tracking::get_exercise_progress(
$sessionId,
@ -1861,6 +1997,7 @@ switch ($action) {
$columns[] = $lesson_id;
}
$columns[] = 'total';
$sidx = in_array($sidx, $columns) ? $sidx : 'username';
$result = SessionManager::get_session_lp_progress(
$sessionId,
$courseId,
@ -1884,7 +2021,6 @@ switch ($action) {
$surveyId = (int) $_GET['survey_id'];
$date_from = $_GET['date_from'];
$date_to = $_GET['date_to'];
//$course = api_get_course_info_by_id($courseId);
}
/**
* Add lessons of course.
@ -1901,6 +2037,7 @@ switch ($action) {
$columns[] = $question_id;
}
$sidx = in_array($sidx, $columns) ? $sidx : 'username';
$result = SessionManager::get_survey_overview(
$sessionId,
$courseId,
@ -1965,6 +2102,7 @@ switch ($action) {
$sessionId = intval($_GET['session_id']);
$courseId = intval($_GET['course_id']);
}
$sidx = in_array($sidx, $columns) ? $sidx : 'username';
$result = SessionManager::get_session_progress(
$sessionId,
$courseId,
@ -1997,6 +2135,7 @@ switch ($action) {
$date_from = intval($_GET['date_from']);
$date_to = intval($_GET['date_to']);
}
$sidx = in_array($sidx, $columns) ? $sidx : 'logindate';
$result = SessionManager::get_user_data_access_tracking_overview(
$sessionId,
@ -2018,6 +2157,7 @@ switch ($action) {
if (!in_array($sidx, $columns)) {
$sidx = 'headline';
}
$sidx = in_array($sidx, $columns) ? $sidx : 'headline';
$course_id = api_get_course_int_id();
$result = Database::select(
'*',
@ -2035,10 +2175,22 @@ switch ($action) {
if (!$item['status']) {
$item['name'] = '<font style="color:#AAA">'.$item['name'].'</font>';
}
$item['headline'] = Display::url($item['headline'], api_get_path(WEB_CODE_PATH).'timeline/view.php?id='.$item['id']);
$item['actions'] = Display::url(Display::return_icon('add.png', get_lang('Add items')), api_get_path(WEB_CODE_PATH).'timeline/?action=add_item&parent_id='.$item['id']);
$item['actions'] .= Display::url(Display::return_icon('edit.png', get_lang('Edit')), api_get_path(WEB_CODE_PATH).'timeline/?action=edit&id='.$item['id']);
$item['actions'] .= Display::url(Display::return_icon('delete.png', get_lang('Delete')), api_get_path(WEB_CODE_PATH).'timeline/?action=delete&id='.$item['id']);
$item['headline'] = Display::url(
$item['headline'],
api_get_path(WEB_CODE_PATH).'timeline/view.php?id='.$item['id']
);
$item['actions'] = Display::url(
Display::return_icon('add.png', get_lang('Add items')),
api_get_path(WEB_CODE_PATH).'timeline/?action=add_item&parent_id='.$item['id']
);
$item['actions'] .= Display::url(
Display::return_icon('edit.png', get_lang('Edit')),
api_get_path(WEB_CODE_PATH).'timeline/?action=edit&id='.$item['id']
);
$item['actions'] .= Display::url(
Display::return_icon('delete.png', get_lang('Delete')),
api_get_path(WEB_CODE_PATH).'timeline/?action=delete&id='.$item['id']
);
$new_result[] = $item;
}
@ -2186,6 +2338,7 @@ switch ($action) {
case 'get_usergroups':
$obj->protectScript();
$columns = ['name', 'users', 'courses', 'sessions', 'group_type', 'actions'];
$sidx = in_array($sidx, $columns) ? $sidx : 'name';
$result = $obj->getUsergroupsPagination($sidx, $sord, $start, $limit, $whereCondition);
break;
case 'get_extra_fields':
@ -2200,6 +2353,7 @@ switch ($action) {
'filter',
'field_order',
];
$sidx = in_array($sidx, $columns) ? $sidx : 'display_text';
$result = $obj->getAllGrid($sidx, $sord, $start, $limit);
$new_result = [];
if (!empty($result)) {
@ -2333,20 +2487,27 @@ switch ($action) {
case 'get_extra_field_options':
$obj = new ExtraFieldOption($type);
$columns = ['display_text', 'option_value', 'option_order'];
$result = $obj->get_all([
$sidx = in_array($sidx, $columns) ? $sidx : 'display_text';
$result = $obj->get_all(
[
'where' => ['field_id = ? ' => $field_id],
'order' => "$sidx $sord",
'LIMIT' => "$start , $limit",
]);
]
);
break;
case 'get_usergroups_teacher':
$columns = ['name', 'users', 'status', 'group_type', 'actions'];
$options['order'] = "name $sord";
$options['limit'] = "$start , $limit";
$options['session_id'] = api_get_session_id();
$options['session_id'] = $sessionId;
switch ($type) {
case 'not_registered':
if (empty($sessionId)) {
$options['where'] = [' (course_id IS NULL OR course_id != ?) ' => $course_id];
} else {
$options['where'] = [' (session_id IS NULL OR session_id != ?) ' => $sessionId];
}
if (!empty($keyword)) {
$options['where']['AND name like %?% '] = $keyword;
}
@ -2388,10 +2549,12 @@ switch ($action) {
$course_id,
api_get_session_id()
)) {
$url = 'class.php?action=remove_class_from_course&id='.$group['id'].'&'.api_get_cidreq().'&id_session='.api_get_session_id();
$url = 'class.php?action=remove_class_from_course&id='.$group['id'].'&'.api_get_cidreq(
).'&id_session='.api_get_session_id();
$icon = Display::return_icon('delete.png', get_lang('Remove'));
} else {
$url = 'class.php?action=add_class_to_course&id='.$group['id'].'&'.api_get_cidreq().'&type=not_registered';
$url = 'class.php?action=add_class_to_course&id='.$group['id'].'&'.api_get_cidreq(
).'&type=not_registered';
$icon = Display::return_icon('add.png', get_lang('Add'));
}
@ -2447,6 +2610,7 @@ $allowed_actions = [
'get_session_progress',
'get_exercise_progress',
'get_exercise_results',
'get_exercise_pending_results',
'get_exercise_results_report',
'get_work_student_list_overview',
'get_work_teacher',
@ -2455,6 +2619,7 @@ $allowed_actions = [
'get_work_user_list',
'get_work_user_list_others',
'get_work_user_list_all',
'get_work_pending_list',
'get_timelines',
'get_grade_models',
'get_user_skill_ranking',

@ -928,7 +928,7 @@ class TicketManager
)
)";
}
$sql .= " ORDER BY $column $direction";
$sql .= " ORDER BY `$column` $direction";
$sql .= " LIMIT $from, $number_of_items";
$result = Database::query($sql);

@ -151,6 +151,7 @@ define('TOOL_ATTENDANCE', 'attendance');
define('TOOL_COURSE_PROGRESS', 'course_progress');
define('TOOL_PORTFOLIO', 'portfolio');
define('TOOL_PLAGIARISM', 'compilatio');
define('TOOL_XAPI', 'xapi');
// CONSTANTS defining Chamilo interface sections
define('SECTION_CAMPUS', 'mycampus');
@ -388,6 +389,7 @@ define('LINK_FORUM_THREAD', 5);
define('LINK_ATTENDANCE', 7);
define('LINK_SURVEY', 8);
define('LINK_HOTPOTATOES', 9);
define('LINK_PORTFOLIO', 10);
// Score display types constants
define('SCORE_DIV', 1); // X / Y
@ -527,6 +529,7 @@ define('ITEM_TYPE_STUDENT_PUBLICATION', 6);
define('ITEM_TYPE_ATTENDANCE', 8);
define('ITEM_TYPE_SURVEY', 9);
define('ITEM_TYPE_FORUM_THREAD', 10);
define('ITEM_TYPE_PORTFOLIO', 11);
// Course description blocks.
define('ADD_BLOCK', 8);
@ -5099,11 +5102,12 @@ function api_get_access_urls($from = 0, $to = 1000000, $order = 'url', $directio
$table = Database::get_main_table(TABLE_MAIN_ACCESS_URL);
$from = (int) $from;
$to = (int) $to;
$order = Database::escape_string($order, null, false);
$direction = Database::escape_string($direction, null, false);
$order = Database::escape_string($order);
$direction = Database::escape_string($direction);
$direction = !in_array(strtolower(trim($direction)), ['asc', 'desc']) ? 'asc' : $direction;
$sql = "SELECT id, url, description, active, created_by, tms
FROM $table
ORDER BY $order $direction
ORDER BY `$order` $direction
LIMIT $to OFFSET $from";
$res = Database::query($sql);
@ -5679,7 +5683,11 @@ function api_is_in_group($groupIdParam = null, $courseCodeParam = null)
*/
function api_is_valid_secret_key($original_key_secret, $security_key)
{
return $original_key_secret == sha1($security_key);
if (empty($original_key_secret) || empty($security_key)) {
return false;
}
return (string) $original_key_secret === sha1($security_key);
}
/**

@ -150,7 +150,7 @@ class CourseManager
public static function get_courses_list(
$from = 0,
$howmany = 0,
$orderby = 1,
$orderby = 'title',
$orderdirection = 'ASC',
$visibility = -1,
$startwith = '',
@ -160,8 +160,6 @@ class CourseManager
$onlyThisCourseList = []
) {
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
//$tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
// @todo fix , course_category.code AS category_code
$sql = "SELECT course.*, course.id as real_id
FROM $courseTable course ";
@ -170,7 +168,6 @@ class CourseManager
$sql .= " INNER JOIN $table url ON (url.c_id = course.id) ";
}
//$sql .= " LEFT JOIN $tblCourseCategory ON course.category_id = course_category.id ";
$visibility = (int) $visibility;
@ -228,26 +225,31 @@ class CourseManager
}
}
if (!empty($orderby)) {
$sql .= " ORDER BY ".Database::escape_string($orderby)." ";
if (empty($orderby)) {
$sql .= ' ORDER BY title ';
} else {
$sql .= ' ORDER BY 1 ';
if (in_array($orderby, ['title'])) {
$sql .= " ORDER BY `".Database::escape_string($orderby)."` ";
} else {
$sql .= ' ORDER BY title ';
}
}
$orderdirection = strtoupper($orderdirection);
if (!in_array($orderdirection, ['ASC', 'DESC'])) {
$sql .= 'ASC';
} else {
$sql .= ('ASC' === $orderdirection ? 'ASC' : 'DESC');
$sql .= $orderdirection === 'ASC' ? 'ASC' : 'DESC';
}
if (!empty($howmany) && is_int($howmany) and $howmany > 0) {
$sql .= ' LIMIT '.Database::escape_string($howmany);
$sql .= ' LIMIT '.(int) $howmany;
} else {
$sql .= ' LIMIT 1000000'; //virtually no limit
}
if (!empty($from)) {
$from = (int) $from;
$sql .= ' OFFSET '.$from;
$from = intval($from);
$sql .= ' OFFSET '.intval($from);
} else {
$sql .= ' OFFSET 0';
}

@ -617,7 +617,7 @@ class Database
if (!empty($order_array)) {
// 'order' => 'id desc, name desc'
$order_array = self::escape_string($order_array, null, false);
$order_array = self::escape_string($order_array);
$new_order_array = explode(',', $order_array);
$temp_value = [];
@ -632,10 +632,10 @@ class Database
if (in_array($element[1], ['desc', 'asc'])) {
$order = $element[1];
}
$temp_value[] = $element[0].' '.$order.' ';
$temp_value[] = ' `'.$element[0].'` '.$order.' ';
} else {
//by default DESC
$temp_value[] = $element[0].' DESC ';
$temp_value[] = ' `'.$element[0].'` DESC ';
}
}
if (!empty($temp_value)) {

@ -2435,9 +2435,7 @@ class Display
*/
public static function getVCardUserLink($userId)
{
$vCardUrl = api_get_path(WEB_PATH).'main/social/vcard_export.php?userId='.intval($userId);
return $vCardUrl;
return api_get_path(WEB_PATH).'main/social/vcard_export.php?userId='.intval($userId);
}
/**

@ -2154,9 +2154,10 @@ HOTSPOT;
$column = !empty($column) ? Database::escape_string($column) : null;
$from = (int) $from;
$number_of_items = (int) $number_of_items;
$direction = !in_array(strtolower(trim($direction)), ['asc', 'desc']) ? 'asc' : $direction;
if (!empty($column)) {
$sql .= " ORDER BY $column $direction ";
$sql .= " ORDER BY `$column` $direction ";
}
if (!$getOnyIds) {

@ -163,6 +163,8 @@ class ExtraField extends Model
case 'portfolio':
$this->extraFieldType = EntityExtraField::PORTFOLIO_TYPE;
break;
case 'lp_view':
$this->extraFieldType = EntityExtraField::LP_VIEW_TYPE;
}
$this->pageUrl = 'extra_fields.php?type='.$this->type;
@ -193,6 +195,7 @@ class ExtraField extends Model
'forum_post',
'exercise',
'track_exercise',
'lp_view',
];
if (api_get_configuration_value('allow_scheduled_announcements')) {
@ -645,7 +648,7 @@ class ExtraField extends Model
$row['display_text']
);
// All the options of the field
// All the tags of the field
$sql = "SELECT * FROM $this->table_field_tag
WHERE field_id='".intval($row['id'])."'
ORDER BY id ASC";
@ -3097,6 +3100,7 @@ JAVASCRIPT;
$tagRelExtraTable = Database::get_main_table(TABLE_MAIN_EXTRA_FIELD_REL_TAG);
$tagTable = Database::get_main_table(TABLE_MAIN_TAG);
$optionsTable = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
$value = Database::escape_string(implode("','", $options));
$sql = "SELECT DISTINCT t.*, v.value, o.display_text
FROM $tagRelExtraTable te
@ -3106,7 +3110,7 @@ JAVASCRIPT;
ON (te.item_id = v.item_id AND v.field_id = $id)
INNER JOIN $optionsTable o
ON (o.option_value = v.value)
WHERE v.value IN ('".implode("','", $options)."')
WHERE v.value IN ('".$value."')
ORDER BY o.option_order, t.tag
";

@ -27,7 +27,7 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
*/
function php2phps($file_name)
{
return preg_replace('/\.(php.?|phtml.?)(\.){0,1}.*$/i', '.phps', $file_name);
return preg_replace('/\.(phar.?|php.?|phtml.?)(\.){0,1}.*$/i', '.phps', $file_name);
}
/**
@ -932,18 +932,6 @@ function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_
/* Uncompressing phase */
/*
The first version, using OS unzip, is not used anymore
because it does not return enough information.
We need to process each individual file in the zip archive to
- add it to the database
- parse & change relative html links
*/
if (PHP_OS == 'Linux' && !get_cfg_var('safe_mode') && false) { // *** UGent, changed by OC ***
// Shell Method - if this is possible, it gains some speed
exec("unzip -d \"".$base_work_dir.$upload_path."/\"".$uploaded_file['name']." ".$uploaded_file['tmp_name']);
} else {
// PHP method - slower...
$save_dir = getcwd();
chdir($base_work_dir.$upload_path);
$unzippingState = $zip_file->extract();
@ -973,7 +961,6 @@ function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_
}
chdir($save_dir); // Back to previous dir position
}
}
return true;
}
@ -1014,6 +1001,9 @@ function unzip_uploaded_document(
$onlyUploadFile = false,
$whatIfFileExists = 'overwrite'
) {
if (empty($courseInfo) || empty($userInfo) || empty($uploaded_file) || empty($uploadPath)) {
return false;
}
$zip = new PclZip($uploaded_file['tmp_name']);
// Check the zip content (real size and file extension)

@ -59,7 +59,7 @@ class Security
}
// Clean $abs_path.
$abs_path = str_replace(['//', '../', './'], ['/', '', ''], $abs_path);
$abs_path = str_replace(['//', '../'], ['/', ''], $abs_path);
$true_path = str_replace("\\", '/', realpath($abs_path));
$checker_path = str_replace("\\", '/', realpath($checker_path));

@ -86,10 +86,10 @@ class ZombieManager
$sql .= ' AND user.active = 1';
}
$sql .= " ORDER BY $column $direction";
$sql .= " ORDER BY `$column` $direction";
if (!is_null($from) && !is_null($count)) {
$count = intval($count);
$from = intval($from);
$count = (int) $count;
$from = (int) $from;
$sql .= " LIMIT $from, $count ";
}

Loading…
Cancel
Save