Update from 1.11.x + fix behat

pull/3890/head
Julio Montoya 4 years ago
parent 5672b3a902
commit 75cb6dbbfc
  1. 3
      public/main/exercise/aiken.php
  2. 2
      public/main/exercise/exercise_global_report.php
  3. 6
      public/main/exercise/exercise_report.php
  4. 6
      public/main/exercise/exercise_result.php
  5. 31
      public/main/exercise/export/aiken/aiken_import.inc.php
  6. 22
      public/main/inc/ajax/model.ajax.php
  7. 3
      public/main/inc/ajax/record_audio_rtc.ajax.php
  8. 2
      public/main/inc/lib/career.lib.php
  9. 17
      public/main/inc/lib/database.lib.php
  10. 37
      public/main/inc/lib/events.lib.php
  11. 11
      public/main/inc/lib/fileUpload.lib.php
  12. 163
      public/main/inc/lib/sessionmanager.lib.php
  13. 1
      public/main/mySpace/access_details.php
  14. 2
      public/main/mySpace/myStudents.php

@ -23,13 +23,12 @@ if (!api_is_allowed_to_edit(null, true)) {
api_not_allowed();
}
// the breadcrumbs
$interbreadcrumb[] = [
'url' => 'exercise.php?'.api_get_cidreq(),
'name' => get_lang('Tests'),
];
$is_allowedToEdit = api_is_allowed_to_edit(null, true);
// import file
if (api_is_allowed_to_edit(null, true)) {
if (isset($_POST['submit'])) {
$id = aiken_import_file($_FILES['userFile']);

@ -48,7 +48,6 @@ $objExercise = new Exercise();
foreach ($students as $studentInfo) {
$studentId = $studentInfo['user_id'];
//$userExtra = UserManager::get_extra_user_data($studentId);
$data = [];
$data[] = $studentInfo['username'];
@ -56,7 +55,6 @@ foreach ($students as $studentInfo) {
$data[] = $studentInfo['firstname'];
$data[] = $studentInfo['email'];
$data[] = $studentInfo['official_code'];
//$data[] = isset($userExtra['extra_nif']) ? $userExtra['extra_nif'] : '';
$userExerciseData = [];
$categoryData = [];

@ -269,7 +269,11 @@ if (isset($_REQUEST['comments']) &&
$res = Database::query($qry);
$tot = 0;
while ($row = Database :: fetch_array($res, 'ASSOC')) {
$tot += $row['marks'];
$marks = $row['marks'];
if (!$objExerciseTmp->propagate_neg && $marks < 0) {
continue;
}
$tot += $marks;
}
} else {
$tot = $pluginEvaluation->getResultWithFormula($id, $formula);

@ -228,14 +228,16 @@ $stats = ExerciseLib::displayQuestionListByAttempt(
$pageContent .= ob_get_contents();
ob_end_clean();
// Change settings for teacher access.
$oldResultDisabled = $objExercise->results_disabled;
$objExercise->results_disabled = RESULT_DISABLE_SHOW_SCORE_AND_EXPECTED_ANSWERS;
$objExercise->forceShowExpectedChoiceColumn = true;
$objExercise->disableHideCorrectAnsweredQuestions = true;
ob_start();
$statsTeacher = ExerciseLib::displayQuestionListByAttempt(
$objExercise,
$exeId,
$saveResults,
false,
$remainingMessage,
$allowSignature,
api_get_configuration_value('quiz_results_answers_report'),
@ -243,8 +245,10 @@ $statsTeacher = ExerciseLib::displayQuestionListByAttempt(
);
ob_end_clean();
// Restore settings.
$objExercise->results_disabled = $oldResultDisabled;
$objExercise->forceShowExpectedChoiceColumn = false;
$objExercise->disableHideCorrectAnsweredQuestions = false;
// Save here LP status
if (!empty($learnpath_id) && $saveResults) {

@ -75,7 +75,8 @@ function get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)
null,
1,
'overwrite',
false
false,
true
)
) {
if (!function_exists('gzopen')) {
@ -115,11 +116,11 @@ function aiken_import_exercise($file)
$archive_path = api_get_path(SYS_ARCHIVE_PATH).'aiken/';
$baseWorkDir = $archive_path;
if (!is_dir($baseWorkDir)) {
mkdir($baseWorkDir, api_get_permissions_for_new_directories(), true);
$uploadPath = 'aiken_'.api_get_unique_id();
if (!is_dir($baseWorkDir.$uploadPath)) {
mkdir($baseWorkDir.$uploadPath, api_get_permissions_for_new_directories(), true);
}
$uploadPath = 'aiken_'.api_get_unique_id().'/';
// set some default values for the new exercise
$exercise_info = [];
@ -133,7 +134,7 @@ function aiken_import_exercise($file)
// unzip the uploaded file in a tmp directory
if (preg_match('/.(zip|txt)$/i', $file)) {
if (!get_and_unzip_uploaded_exercise($baseWorkDir, $uploadPath)) {
if (!get_and_unzip_uploaded_exercise($baseWorkDir.$uploadPath, '/')) {
return 'ThereWasAProblemWithYourFile';
}
}
@ -182,10 +183,9 @@ function aiken_import_exercise($file)
$tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION);
$tableAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
if (!empty($last_exercise_id)) {
// For each question found...
$courseId = api_get_course_int_id();
foreach ($exercise_info['question'] as $key => $question_array) {
// 2.create question
// 2. Create question.
$question = new Aiken2Question();
$question->type = $question_array['type'];
$question->setAnswer();
@ -260,8 +260,6 @@ function aiken_import_exercise($file)
$max_score = $scoreFromFile;
}
//$answer->save();
$params = ['ponderation' => $max_score];
Database::update(
$tableQuestion,
@ -315,7 +313,6 @@ function aiken_parse_file(&$exercise_info, $exercisePath, $file, $questionFile)
foreach ($data as $line => $info) {
$info = trim($info);
if (empty($info)) {
// double empty line
continue;
}
//make sure it is transformed from iso-8859-1 to utf-8 if in that form
@ -339,6 +336,9 @@ function aiken_parse_file(&$exercise_info, $exercisePath, $file, $questionFile)
continue;
}
if (false !== strpos($data[$next], 'DESCRIPTION:')) {
continue;
}
// Check if next has score, otherwise loop too next question.
if (false === strpos($data[$next], 'SCORE:')) {
$answers_array = [];
@ -352,6 +352,17 @@ function aiken_parse_file(&$exercise_info, $exercisePath, $file, $questionFile)
continue;
} elseif (preg_match('/^DESCRIPTION:\s?(.*)/', $info, $matches)) {
$exercise_info['question'][$question_index]['description'] = $matches[1];
$next = $line + 1;
if (false !== strpos($data[$next], 'ANSWER_EXPLANATION:')) {
continue;
}
// Check if next has score, otherwise loop too next question.
if (false === strpos($data[$next], 'SCORE:')) {
$answers_array = [];
$question_index++;
continue;
}
} elseif (preg_match('/^ANSWER_EXPLANATION:\s?(.*)/', $info, $matches)) {
//Comment of correct answer
$correct_answer_index = array_search($matches[1], $answers_array);

@ -1774,6 +1774,9 @@ switch ($action) {
);
break;
case 'get_sessions_tracking':
$sessionColumns = SessionManager::getGridColumns('my_space');
$columns = $sessionColumns['simple_column_name'];
if (api_is_drh()) {
$orderByName = Database::escape_string($sidx);
$orderByName = in_array($orderByName, ['name', 'access_start_date']) ? $orderByName : 'name';
@ -1823,9 +1826,6 @@ switch ($action) {
);
}
$sessionColumns = SessionManager::getGridColumns('my_space');
$columns = $sessionColumns['simple_column_name'];
$result = [];
if (!empty($sessions)) {
$pdfIcon = Display::return_icon('pdf.png', get_lang('CertificateOfAchievement'), [], ICON_SIZE_SMALL);
@ -1989,10 +1989,7 @@ switch ($action) {
'firstname',
'lastname',
];
$lessons = LearnpathList::get_course_lessons(
$course['code'],
$sessionId
);
$lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
foreach ($lessons as $lesson_id => $lesson) {
$columns[] = $lesson_id;
}
@ -2382,10 +2379,7 @@ switch ($action) {
break;
case 'get_exercise_grade':
$objExercise = new Exercise();
$exercises = $objExercise->getExercisesByCourseSession(
$_GET['course_id'],
$_GET['session_id']
);
$exercises = $objExercise->getExercisesByCourseSession($_GET['course_id'], $_GET['session_id']);
$cntExer = 4;
if (!empty($exercises)) {
$cntExer += count($exercises);
@ -2488,13 +2482,11 @@ switch ($action) {
$obj = new ExtraFieldOption($type);
$columns = ['display_text', 'option_value', 'option_order'];
$sidx = in_array($sidx, $columns) ? $sidx : 'display_text';
$result = $obj->get_all(
[
$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'];

@ -69,7 +69,8 @@ switch ($type) {
api_get_user_id(),
$courseInfo,
api_get_session_id(),
api_get_group_id()
api_get_group_id(),
true
);
$error = empty($uploadedDocument) || !is_array($uploadedDocument);

@ -951,7 +951,7 @@ class Career extends Model
$originalRow--;
$column--;
//$title = "$originalRow / $column";
$graphHtml .= Display::panel(
$content,
$title,

@ -519,24 +519,39 @@ class Database
$option = 'ASSOC',
$debug = false
) {
if ($type_result === 'count') {
$conditions['LIMIT'] = null;
$conditions['limit'] = null;
}
$conditions = self::parse_conditions($conditions);
//@todo we could do a describe here to check the columns ...
if (is_array($columns)) {
$clean_columns = implode(',', $columns);
} else {
if ('*' == $columns) {
if ('*' === $columns) {
$clean_columns = '*';
} else {
$clean_columns = (string) $columns;
}
}
if ($type_result === 'count') {
$clean_columns = ' count(*) count ';
}
$sql = "SELECT $clean_columns FROM $table_name $conditions";
if ($debug) {
var_dump($sql);
}
$result = self::query($sql);
if ($type_result === 'count') {
$row = self::fetch_array($result, $option);
if ($row) {
return (int) $row['count'];
}
return 0;
}
$array = [];
if ('all' === $type_result) {

@ -560,14 +560,13 @@ class Event
return false;
}
if (null === $answer) {
$answer = '';
}
if (null === $score) {
$score = 0;
}
if (null != $answer) {
$answer = (int) $answer;
}
$attempt = [
'user_id' => $user_id,
'question_id' => $question_id,
@ -694,14 +693,16 @@ class Event
$answerId,
$correct,
$coords,
$updateResults = false
$updateResults = false,
$exerciseId = 0,
$lpId = 0,
$lpItemId = 0
) {
$debug = false;
global $safe_lp_id, $safe_lp_item_id;
if (false == $updateResults) {
if ($updateResults == false) {
// Validation in case of fraud with activated control time
if (!ExerciseLib::exercise_time_control_is_valid($exercise, $safe_lp_id, $safe_lp_item_id)) {
if (!ExerciseLib::exercise_time_control_is_valid($exerciseId, $lpId, $lpItemId)) {
if ($debug) {
error_log('Attempt is fraud');
}
@ -850,6 +851,26 @@ class Event
return true;
}
public static function findUserSubscriptionToCourse(int $userId, int $courseId, int $sessionId = 0)
{
$tblTrackEDefault = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
return Database::select(
'*',
$tblTrackEDefault,
[
'where' => [
'default_event_type = ? AND ' => LOG_SUBSCRIBE_USER_TO_COURSE,
'default_value_type = ? AND ' => LOG_USER_OBJECT,
'default_value LIKE ? AND ' => '%s:2:\\\\"id\\\\";i:'.$userId.'%',
'c_id = ? AND ' => $courseId,
'session_id = ?' => $sessionId,
],
],
'first'
);
}
/**
* Gets the last attempt of an exercise based in the exe_id.
*

@ -254,7 +254,7 @@ function handle_uploaded_document(
$parentId = 0,
$content = null
) {
if (!$userId) {
if (empty($uploadedFile) || empty($userId) || empty($courseInfo) || empty($documentDir) || empty($uploadPath)) {
return false;
}
@ -880,8 +880,12 @@ function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_
$zip_content_array = $zip_file->listContent();
$ok_scorm = false;
$realFileSize = 0;
foreach ($zip_content_array as &$this_content) {
if (preg_match('~.(php.*|phtml)$~i', $this_content['filename'])) {
$ok_plantyn_scorm1 = false;
$ok_plantyn_scorm2 = false;
$ok_plantyn_scorm3 = false;
$ok_aicc_scorm = false;
foreach ($zip_content_array as $this_content) {
if (preg_match('~.(php.*|phtml|phar|htaccess)$~i', $this_content['filename'])) {
Display::addFlash(
Display::return_message(get_lang('The zip file can not contain .PHP files'))
);
@ -950,6 +954,7 @@ function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_
}
$safe_file = api_replace_dangerous_char($file);
$safe_file = disable_dangerous_file($safe_file);
@rename($base_work_dir.$upload_path.'/'.$file, $base_work_dir.$upload_path.'/'.$safe_file);
set_default_settings($upload_path, $safe_file, $filetype);
}

@ -6050,7 +6050,7 @@ class SessionManager
$getCount = false,
$from = null,
$numberItems = null,
$column = 1,
$column = '',
$direction = 'asc',
$keyword = null,
$active = null,
@ -6062,6 +6062,12 @@ class SessionManager
$filterByStatus = (int) $filterByStatus;
$userId = (int) $userId;
if (empty($column)) {
$column = 'u.lastname';
if (api_is_western_name_order()) {
$column = 'u.firstname';
}
}
$tbl_user = Database::get_main_table(TABLE_MAIN_USER);
$tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
@ -6735,15 +6741,32 @@ class SessionManager
if (!empty($list)) {
$userSessionList = [];
foreach ($list as $data) {
$userInfo = api_get_user_info_from_username($data['Username']);
$sessionInfo = [];
if (isset($data['SessionId'])) {
$sessionInfo = api_get_session_info($data['SessionId']);
}
if (isset($data['SessionName']) && empty($sessionInfo)) {
$sessionInfo = self::get_session_by_name($data['SessionName']);
}
if (empty($sessionInfo)) {
Display::addFlash(Display::return_message(get_lang('The session was not identified').' - '.$data['SessionName'], 'warning'));
$sessionData = isset($data['SessionName']) ? $data['SessionName'] : $data['SessionId'];
Display::addFlash(
Display::return_message(get_lang('SessionNotFound').' - '.$sessionData, 'warning')
);
continue;
}
$userList = explode(',', $data['Username']);
foreach ($userList as $username) {
$userInfo = api_get_user_info_from_username($username);
if (empty($userInfo)) {
Display::addFlash(Display::return_message(get_lang('This user doesn\'t exist').' - '.$data['Username'], 'warning'));
Display::addFlash(
Display::return_message(get_lang('UserDoesNotExist').' - '.$username, 'warning')
);
continue;
}
if (!empty($userInfo) && !empty($sessionInfo)) {
@ -6754,6 +6777,7 @@ class SessionManager
$userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
}
}
}
self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
@ -9560,6 +9584,137 @@ class SessionManager
}
}
public static function insertUsersInCourses(array $studentIds, array $courseIds, int $sessionId)
{
$tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
$tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
foreach ($courseIds as $courseId) {
self::insertUsersInCourse($studentIds, $courseId, $sessionId, [], false);
}
foreach ($studentIds as $studentId) {
Database::query(
"INSERT IGNORE INTO $tblSessionUser (session_id, user_id, registered_at)
VALUES ($sessionId, $studentId, '".api_get_utc_datetime()."')"
);
}
Database::query(
"UPDATE $tblSession s
SET s.nbr_users = (
SELECT COUNT(1) FROM session_rel_user sru
WHERE sru.session_id = $sessionId AND sru.relation_type <> ".Session::DRH."
)
WHERE s.id = $sessionId"
);
}
public static function insertUsersInCourse(
array $studentIds,
int $courseId,
int $sessionId,
array $relationInfo = [],
bool $updateSession = true
) {
$tblSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
$tblSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
$tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
$tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
$relationInfo = array_merge(['visiblity' => 0, 'status' => Session::STUDENT], $relationInfo);
$sessionCourseUser = [
'session_id' => $sessionId,
'c_id' => $courseId,
'visibility' => $relationInfo['visibility'],
'status' => $relationInfo['status'],
];
$sessionUser = [
'session_id' => $sessionId,
'registered_at' => api_get_utc_datetime(),
];
foreach ($studentIds as $studentId) {
$sessionCourseUser['user_id'] = $studentId;
Database::insert($tblSessionCourseUser, $sessionCourseUser);
if ($updateSession) {
$sessionUser['user_id'] = $studentId;
Database::insert($tblSessionUser, $sessionUser);
}
Event::logUserSubscribedInCourseSession($studentId, $courseId, $sessionId);
}
Database::query(
"UPDATE $tblSessionCourse src
SET src.nbr_users = (
SELECT COUNT(1) FROM $tblSessionCourseUser srcru
WHERE
srcru.session_id = $sessionId AND srcru.c_id = $courseId AND srcru.status <> ".Session::COACH."
)
WHERE src.session_id = $sessionId AND src.c_id = $courseId"
);
if ($updateSession) {
Database::query(
"UPDATE $tblSession s
SET s.nbr_users = (
SELECT COUNT(1) FROM session_rel_user sru
WHERE sru.session_id = $sessionId AND sru.relation_type <> ".Session::DRH."
)
WHERE s.id = $sessionId"
);
}
}
public static function getCareerDiagramPerSession($sessionId, $userId): string
{
$extraFieldValueSession = new ExtraFieldValue('session');
$extraFieldValueCareer = new ExtraFieldValue('career');
$visibility = api_get_session_visibility($sessionId, null, false, $userId);
$content = '';
if (SESSION_AVAILABLE === $visibility) {
$value = $extraFieldValueSession->get_values_by_handler_and_field_variable($sessionId, 'careerid');
if (isset($value['value']) && !empty($value['value'])) {
$careerList = str_replace(['[', ']'], '', $value['value']);
$careerList = explode(',', $careerList);
foreach ($careerList as $career) {
$careerIdValue = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
'external_career_id',
$career
);
if (isset($careerIdValue['item_id']) && !empty($careerIdValue['item_id'])) {
$finalCareerId = $careerIdValue['item_id'];
$career = new Career();
$careerInfo = $career->get($finalCareerId);
if (!empty($careerInfo)) {
$careerUrl = api_get_path(WEB_CODE_PATH).
'user/career_diagram.php?iframe=1&career_id='.$finalCareerId;
$content .= '<iframe
style="width:100%; height:500px"
border="0"
frameborder="0"
src="'.$careerUrl.'"></iframe>';
}
}
}
}
}
if (!empty($content)) {
$content = Display::page_subheader(get_lang('OngoingTraining')).$content;
}
return $content;
}
private static function allowed(?Session $session = null): bool
{
if (api_is_platform_admin()) {

@ -15,7 +15,6 @@ require_once __DIR__.'/../inc/global.inc.php';
api_block_anonymous_users();
// Access restrictions.
$allowToTrack = api_is_platform_admin(true, true) ||
api_is_teacher() || api_is_course_tutor();

@ -19,6 +19,7 @@ api_block_anonymous_users();
$htmlHeadXtra[] = null;
$export = $_GET['export'] ?? false;
$sessionId = isset($_GET['sid']) ? (int) $_GET['sid'] : 0;
$action = $_GET['action'] ?? '';
$origin = api_get_origin();
$courseId = isset($_GET['cid']) ? (int) $_GET['cid'] : '';
$course = api_get_course_entity($courseId);
@ -211,7 +212,6 @@ if (!empty($details)) {
// Database Table Definitions
$tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
$tbl_stats_exercices = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
$action = $_GET['action'] ?? '';
switch ($action) {
case 'add_work_time':

Loading…
Cancel
Save