/** * Copy test * * This function copies a test into the current content tree * <br/>Example: * <code> * $currentContent = new EfrontContentTree(5); //Initialize content for lesson with id 5 * $currentContent -> copyTest(3, false); //Copy the corresponding test into the content tree (at its end) * </code> * * @param int $testId The id of the test to be copied * @param mixed $targetUnit The id of the parent unit (or the parent EfrontUnit)in which the new unit will be copied, or false (the unit will be appended at the end) * @param boolean $copyQuestions Whether to copy questions as well. Copied questions will be attached to the test itself as parent unit * @return EfrontUnit The newly created test unit object * @since 3.5.0 * @access public */ public function copyTest($testId, $targetUnit = false, $copyQuestions = true, $copyFiles = true, $linked_to = false) { $oldTest = new EfrontTest($testId); $oldUnit = $oldTest->getUnit(); $oldUnit['data'] = $oldTest->test['description']; //Hack in order to successfully copy files. It will be removed when we implement the new copy/export framework $newUnit = $this->copySimpleUnit($oldUnit, $targetUnit); $oldTest->test['description'] = $newUnit['data']; //As above $newTest = EfrontTest::createTest($newUnit, $oldTest->test); $newUnit['data'] = ''; //As above $newUnit->persist(); //As above if ($copyQuestions) { $testQuestions = $oldTest->getQuestions(true); $newQuestions = array(); if (sizeof($testQuestions) > 0) { $result = eF_getTableData("questions", "*", "id in (" . implode(",", array_keys($testQuestions)) . ")"); foreach ($result as $value) { $questionData[$value['id']] = $value; unset($questionData[$value['id']]['id']); } } $ids_mapping = array(); $lesson = new EfrontLesson($newUnit->offsetGet('lessons_ID')); $folderId = $lesson->lesson['share_folder'] ? $lesson->lesson['share_folder'] : $lesson->lesson['id']; foreach ($testQuestions as $key => $oldQuestion) { $questionData[$key]['content_ID'] = $newUnit->offsetGet('id'); $questionData[$key]['lessons_ID'] = $newUnit->offsetGet('lessons_ID'); if ($copyFiles) { $questionData[$key]['text'] = replaceQuestionPaths($questionData[$key]['text'], $oldUnit['lessons_ID'], $folderId); $questionData[$key]['explanation'] = replaceQuestionPaths($questionData[$key]['explanation'], $oldUnit['lessons_ID'], $folderId); } $newQuestion = Question::createQuestion($questionData[$key]); $qid = $newQuestion->question['id']; if ($linked_to) { $newQuestion->question['linked_to'] = $oldQuestion->question['id']; $newQuestion->persist(); } $newQuestions[$qid] = $oldTest->getAbsoluteQuestionWeight($oldQuestion->question['id']); $ids_mapping[$oldQuestion->question['id']] = $qid; } //code for sorting $newQuestions based on $oldQuestion in order to be copied in same order(#2962) $newQuestionsSorted = array(); foreach ($testQuestions as $key => $oldQuestion) { $newQuestionsSorted[$ids_mapping[$key]] = $newQuestions[$ids_mapping[$key]]; } $newQuestions = $newQuestionsSorted; $newTest->addQuestions($newQuestions); } return $newUnit; }
/** * Create new user * * This function is used to create a new user in the system * The user is created based on a a properties array, in which * the user login, name, surname and email must be present, otherwise * an EfrontUserException is thrown. Apart from these, all the other * user elements are optional, and defaults will be used if they are left * blank. * Once the database representation is created, the constructor tries to create the * user directories, G_UPLOADPATH.'login/' and message attachments subfolders. Finally * it assigns a default avatar to the user. The function instantiates the user based on * its type. * <br/>Example: * <code> * $properties = array('login' => 'jdoe', 'name' => 'john', 'surname' => 'doe', 'email' => '*****@*****.**'); * $user = EfrontUser :: createUser($properties); * </code> * * @param array $userProperties The new user properties * @param array $users The list of existing users, with logins and active properties, in the form array($login => $active). It is handy to specify when creating massively users * @return array with new user settings if the new user was successfully created * @since 3.5.0 * @access public */ public static function createUser($userProperties, $users = array(), $addToDefaultGroup = true) { $result = eF_getTableData("users", "count(id) as total", "active=1"); $activatedUsers = $result[0]['total']; if (!isset($userProperties['login']) || !eF_checkParameter($userProperties['login'], 'login')) { throw new EfrontUserException(_INVALIDLOGIN . ': ' . $userProperties['login'], EfrontUserException::INVALID_LOGIN); } $result = eF_getTableData("users", "login, archive", "login='******'login']}'"); //collation is by default utf8_general_ci, meaning that this search is case-insensitive if (sizeof($result) > 0) { if ($result[0]['archive']) { throw new EfrontUserException(_USERALREADYEXISTSARCHIVED . ': ' . $userProperties['login'], EfrontUserException::USER_EXISTS); } else { throw new EfrontUserException(_USERALREADYEXISTS . ': ' . $userProperties['login'], EfrontUserException::USER_EXISTS); } } /* $archived_keys = array_combine(array_keys($archived),array_keys($archived)); if (isset($archived_keys[mb_strtolower($userProperties['login'])])) { //if (in_array(mb_strtolower($userProperties['login']), array_keys($archived), true) !== false) { throw new EfrontUserException(_USERALREADYEXISTSARCHIVED.': '.$userProperties['login'], EfrontUserException :: USER_EXISTS); } $user_keys = array_combine(array_keys($users),array_keys($users)); if (isset($user_keys[mb_strtolower($userProperties['login'])])) { //if (in_array(mb_strtolower($userProperties['login']), array_keys($users), true) !== false) { throw new EfrontUserException(_USERALREADYEXISTS.': '.$userProperties['login'], EfrontUserException :: USER_EXISTS); } */ if (G_VERSIONTYPE != 'community') { #cpp#ifndef COMMUNITY if (G_VERSIONTYPE != 'standard') { #cpp#ifndef STANDARD //pr($activatedUsers); if (isset($GLOBALS['configuration']['version_users']) && $activatedUsers > $GLOBALS['configuration']['version_users'] && $GLOBALS['configuration']['version_users'] > 0) { throw new EfrontUserException(_MAXIMUMUSERSNUMBERREACHED . ' (' . $GLOBALS['configuration']['version_users'] . '): ' . $userProperties['login'], EfrontUserException::MAXIMUM_REACHED); } } #cpp#endif } #cpp#endif if ($userProperties['email'] && !eF_checkParameter($userProperties['email'], 'email')) { throw new EfrontUserException(_INVALIDEMAIL . ': ' . $userProperties['email'], EfrontUserException::INVALID_PARAMETER); } if (!isset($userProperties['name'])) { throw new EfrontUserException(_INVALIDNAME . ': ' . $userProperties['name'], EfrontUserException::INVALID_PARAMETER); } if (!isset($userProperties['surname'])) { throw new EfrontUserException(_INVALIDSURNAME . ': ' . $userProperties['login'], EfrontUserException::INVALID_PARAMETER); } $roles = EfrontUser::getRoles(); $rolesTypes = EfrontUser::getRoles(true); foreach (EfrontUser::getRoles(true) as $key => $value) { $rolesTypes[$key] = mb_strtolower($value); } //If a user type is not specified, by default make the new user student if (!isset($userProperties['user_type'])) { $userProperties['user_type'] = 'student'; } else { if (in_array(mb_strtolower($userProperties['user_type']), $roles)) { $userProperties['user_type'] = mb_strtolower($userProperties['user_type']); } else { if ($k = array_search(mb_strtolower($userProperties['user_type']), $rolesTypes)) { $userProperties['user_types_ID'] = $k; $userProperties['user_type'] = $roles[$k]; } else { $userProperties['user_type'] = 'student'; } } } if (!in_array($userProperties['user_type'], EFrontUser::$basicUserTypes)) { $userProperties['user_type'] = 'student'; $userProperties['user_types_ID'] = 0; } //!isset($userProperties['user_type']) || !in_array($userProperties['user_type'], EfrontUser::getRoles()) ? $userProperties['user_type'] = 'student' : null; isset($userProperties['password']) && $userProperties['password'] != '' ? $passwordNonTransformed = $userProperties['password'] : ($passwordNonTransformed = $userProperties['login']); if ($userProperties['password'] != 'ldap') { !isset($userProperties['password']) || $userProperties['password'] == '' ? $userProperties['password'] = EfrontUser::createPassword($userProperties['login']) : ($userProperties['password'] = self::createPassword($userProperties['password'])); if ($GLOBALS['configuration']['force_change_password']) { $userProperties['need_pwd_change'] = 1; } } !isset($userProperties['email']) ? $userProperties['email'] = '' : null; // 0 means not pending, 1 means pending !isset($userProperties['languages_NAME']) ? $userProperties['languages_NAME'] = $GLOBALS['configuration']['default_language'] : null; //If language is not specified, use default language !isset($userProperties['active']) || $userProperties['active'] == "" ? $userProperties['active'] = 0 : null; // 0 means inactive, 1 means active !isset($userProperties['pending']) ? $userProperties['pending'] = 0 : null; // 0 means not pending, 1 means pending !isset($userProperties['timestamp']) || $userProperties['timestamp'] == "" ? $userProperties['timestamp'] = time() : null; !isset($userProperties['user_types_ID']) ? $userProperties['user_types_ID'] = 0 : null; $languages = EfrontSystem::getLanguages(); if (in_array($userProperties['languages_NAME'], array_keys($languages)) === false) { $userProperties['languages_NAME'] = $GLOBALS['configuration']['default_language']; } if ($userProperties['archive']) { $userProperties['archive'] = time(); $userProperties['active'] = 0; } !isset($userProperties['timezone']) || $userProperties['timezone'] == '' ? $userProperties['timezone'] = $GLOBALS['configuration']['time_zone'] : null; $userProfile = eF_getTableData("user_profile", "name,options", "active=1 AND type='select'"); foreach ($userProfile as $field) { if (isset($userProperties[$field['name']])) { $options = unserialize($field['options']); $userProperties[$field['name']] = array_search($userProperties[$field['name']], $options); } } eF_insertTableData("users", $userProperties); // Assign to the new user all skillgap tests that should be automatically assigned to every new student if (G_VERSIONTYPE != 'community') { #cpp#ifndef COMMUNITY if (G_VERSIONTYPE != 'standard') { #cpp#ifndef STANDARD if ($userProperties['user_type'] == 'student') { $tests = EfrontTest::getAutoAssignedTests(); foreach ($tests as $test) { eF_insertTableData("users_to_skillgap_tests", array("users_LOGIN" => $userProperties['login'], "tests_ID" => $test)); } } } #cpp#endif } #cpp#endif $newUser = EfrontUserFactory::factory($userProperties['login']); //$newUser -> user['password'] = $passwordNonTransformed; //commented out because it was not needed any more, and created problems. Will be removed in next pass global $currentUser; // this is for running eF_loadAllModules ..needs to go somewhere else if (!$currentUser) { $currentUser = $newUser; } EfrontEvent::triggerEvent(array("type" => EfrontEvent::SYSTEM_JOIN, "users_LOGIN" => $newUser->user['login'], "users_name" => $newUser->user['name'], "users_surname" => $newUser->user['surname'], "entity_name" => $passwordNonTransformed)); EfrontEvent::triggerEvent(array("type" => -1 * EfrontEvent::SYSTEM_VISITED, "users_LOGIN" => $newUser->user['login'], "users_name" => $newUser->user['name'], "users_surname" => $newUser->user['surname'])); if (G_VERSIONTYPE != 'community') { #cpp#ifndef COMMUNITY if (G_VERSIONTYPE != 'standard') { #cpp#ifndef STANDARD if ($addToDefaultGroup) { EfrontGroup::addToDefaultGroup($newUser, $newUser->user['user_types_ID'] ? $newUser->user['user_types_ID'] : $newUser->user['user_type']); } } #cpp#endif } #cpp#endif ///MODULES1 - Module user add events // Get all modules (NOT only the ones that have to do with the user type) if (!self::$cached_modules) { self::$cached_modules = eF_loadAllModules(); } // Trigger all necessary events. If the function has not been re-defined in the derived module class, nothing will happen foreach (self::$cached_modules as $module) { $module->onNewUser($userProperties['login']); } EfrontCache::getInstance()->deleteCache('usernames'); if (G_VERSIONTYPE != 'community') { #cpp#ifndef COMMUNITY if (G_VERSIONTYPE != 'standard') { #cpp#ifndef STANDARD $threshold = self::NOTIFY_THRESHOLD * $GLOBALS['configuration']['version_users']; if (isset($GLOBALS['configuration']['version_users']) && $GLOBALS['configuration']['version_users'] > 0 && $activatedUsers < $threshold && $activatedUsers + 1 > $threshold) { $admin = EfrontSystem::getAdministrator(); eF_mail($GLOBALS['configuration']['system_email'], $admin->user['email'], _YOUAREREACHINGYOURSUBSCRIPTIONLIMIT, str_replace(array('%w', '%x', '%y', '%z'), array($admin->user['name'], self::NOTIFY_THRESHOLD * 100, $GLOBALS['configuration']['site_name'], G_SERVERNAME), _YOUAREREACHINGYOURSUBSCRIPTIONLIMITBODY)); } } #cpp#endif } #cpp#endif return $newUser; }
/***/ require_once "glossary.php"; } elseif ($ctg == 'survey') { if (!EfrontUser::isOptionVisible('surveys')) { eF_redirect("" . basename($_SERVER['PHP_SELF']) . "?ctg=control_panel&message=" . urlencode(_UNAUTHORIZEDACCESS) . "&message_type=failure"); } $load_editor = true; include_once "module_surveys.php"; } elseif ($ctg == 'statistics') { if (isset($_GET['show_solved_test']) && eF_checkParameter($_GET['show_solved_test'], 'id') && isset($_GET['lesson']) && eF_checkParameter($_GET['lesson'], 'id')) { try { //pr($_GET['lesson']);pr($currentUser -> getLessons()); if (in_array($_GET['lesson'], array_keys($currentUser->getLessons()))) { $result = eF_getTableData("done_tests, tests, content", "done_tests.tests_ID, done_tests.users_LOGIN", "content.id=tests.content_ID and content.lessons_ID=" . $_GET['lesson'] . " and tests.id = done_tests.tests_ID and done_tests.users_LOGIN = '******'login'] . "' and done_tests.id=" . $_GET['show_solved_test']); if (sizeof($result) > 0) { $showTest = new EfrontTest($result[0]['tests_ID']); //Set "show answers" and "show given answers" to true, since if it is not the student that sees the test if ($currentUser->user['user_type'] != 'student') { $showTest->options['answers'] = 1; $showTest->options['given_answers'] = 1; } $showTest->setDone($result[0]['users_LOGIN']); $smarty->assign("T_CURRENT_TEST", $showTest->test); $smarty->assign("T_SOLVED_TEST_DATA", $showTest->doneInfo); $smarty->assign("T_TEST_SOLVED", $showTest->toHTMLQuickForm(new HTML_Quickform(), false, true)); } else { $message = _USERHASNOTDONETEST; $message_type = 'failure'; } } else { $message = _USERHASNOTTHISLESSON;
$showTest = new EfrontTest($_GET['view_unit'], true); if (isset($_GET['show_all'])) { $showTest->options['random_pool'] = false; $showTest->options['onebyone'] = 0; } if (isset($_GET['preview_correct']) && $_SESSION['s_lesson_user_type'] != 'student') { $showTest->preview_correct = true; } if (isset($_GET['print'])) { $testString = $showTest->toHTML($showTest->toHTMLQuickForm(), false, true); } else { $testString = $showTest->toHTML($showTest->toHTMLQuickForm(), false); } $smarty->assign("T_TEST", $testString); } else { $test = new EfrontTest($currentUnit['id'], true); $status = $test->getStatus($currentUser, $_GET['show_solved_test']); $form = new HTML_QuickForm("test_form", "post", basename($_SERVER['PHP_SELF']) . '?view_unit=' . $_GET['view_unit'], "", 'onsubmit = "$(\'submit_test\').disabled=true;"', true); switch ($status['status']) { case 'incomplete': //$test -> getQuestionsRandomTest(true); if (!($testInstance = unserialize($status['completedTest']['test']))) { throw new EfrontTestException(_TESTCORRUPTEDASKRESETEXECUTION, EfrontTestException::CORRUPTED_TEST); } if ($testInstance->time['pause'] && isset($_GET['resume'])) { $testInstance->time['pause'] = 0; $testInstance->time['resume'] = time(); //unset($testInstance -> currentQuestion); $testInstance->save(); } $remainingTime = $testInstance->options['duration'] - $testInstance->time['spent'] - (time() - $testInstance->time['resume']);
$count[$cnt++] = ceil($value / 60); } $graph = new EfrontGraph(); $graph->type = 'line'; for ($i = 0; $i < sizeof($labels); $i++) { $graph->data[] = array($i, $count[$i]); $graph->xLabels[] = array($i, formatTimestamp($labels[$i])); } $graph->xTitle = _DAY; $graph->yTitle = _MINUTES; $graph->title = _MINUTESPERDAY; echo json_encode($graph); exit; } else { if (isset($_GET['ajax']) && $_GET['ajax'] == 'graph_test_questions') { $test = new EfrontTest($_GET['entity']); $types = array(); foreach ($test->getQuestions() as $value) { isset($types[$value['type']]) ? $types[$value['type']]++ : ($types[$value['type']] = 1); } $graph = new EfrontGraph(); $graph->type = 'pie'; $count = 0; foreach ($types as $key => $value) { $graph->data[] = array(array($count, $value)); $graph->labels[] = array(Question::$questionTypes[$key]); } echo json_encode($graph); exit; } }
$testInstance->options['pause_test'] = 0; $testString = $testInstance->toHTMLQuickForm($form); $testString = $testInstance->toHTML($testString, $remainingTime); $form->addElement('hidden', 'time_start', $timeStart); //This element holds the time the test started, so we know the remaining time even if the user left the system $form->addElement('submit', 'submit_test', _SUBMITTEST, 'class = "flatButton" onclick = "if (typeof(checkedQuestions) != \'undefined\' && (unfinished = checkQuestions())) return confirm(\'' . _YOUHAVENOTCOMPLETEDTHEFOLLOWINGQUESTIONS . ': \'+unfinished+\'. ' . _AREYOUSUREYOUWANTTOSUBMITTEST . '\');"'); if ($testInstance->options['pause_test']) { $form->addElement('submit', 'pause_test', _PAUSETEST, 'class = "flatButton"'); } $renderer = new HTML_QuickForm_Renderer_ArraySmarty($smarty); $form->accept($renderer); $smarty->assign('T_TEST_FORM', $renderer->toArray()); // eF_redirect("".basename($_SERVER['PHP_SELF'])."?ctg=lessons&op=tests&"); } else { $form = new HTML_QuickForm("test_form", "post", basename($_SERVER['PHP_SELF']) . '?ctg=lessons&op=tests', "", null, true); $test = new EfrontTest($_GET['solve_test']); $testInstance = $test; $test->getQuestions(); //This way the test's questions are populated, and we will be needing this information $testInstance->options['random_pool'] && $testInstance->options['random_pool'] >= sizeof($testIn) ? $questionsNumber = $testInstance->options['random_pool'] : ($questionsNumber = sizeof($testInstance->questions)); $smarty->assign("T_SHOW_CONFIRMATION", true); } if (isset($_GET['ajax'])) { $testInstance->handleAjaxActions(); } //Calculate total questions. If it's already set, then we are visiting an unsolved test, and the questions number is already calculated (and may be different that the $testInstance -> questions size) if (!isset($questionsNumber)) { $questionsNumber = sizeof($testInstance->questions); } //$smarty -> assign("T_REMAINING_TIME", $remainingTime); $smarty->assign("T_TEST_QUESTIONS_NUM", $questionsNumber);
/** * Get statistic information about tests * * This returns statistic info for a test * <br/>Example: * <code> * $tests = array(2, 4); * $info = EfrontStats :: getTestInfo($tests); //Get information for tests 2,4 * </code> * @param mixed $tests Either an array of tests id or false (request information for all existing tests) * @param mixed $categories denotes in how many categories will the scores from 0-100% be divided (if not false) * @param mixed $show_all: denotes whether the function should return the stats for all the times a user took a test (default=no: just return for the active test) * @return array the tests' statistinc info * @since 3.5.0 * @access public * @static */ public static function getTestInfo($tests = false, $categories = false, $show_all = false, $lesson = false, $users = false) { if ($tests == false) { $tests = eF_getTableDataFlat("tests, content", "tests.id", "tests.content_ID=content.id and content.ctg_type = 'tests' and tests.lessons_ID != 0"); //This way we get tests that have a corresponding unit $tests = $tests['id']; } elseif (!is_array($tests)) { $tests = array($tests); } $lessonNames = eF_getTableDataFlat("lessons", "id,name"); sizeof($lessonNames) > 0 ? $lessonNames = array_combine($lessonNames['id'], $lessonNames['name']) : ($lessonNames = array()); if (!$users) { if ($lesson) { $lessonUsers = eF_getTableDataFlat("users_to_lessons ul, users u", "ul.users_LOGIN", "u.login=ul.users_LOGIN and u.archive=0 and ul.lessons_ID={$lesson} and ul.archive=0"); $users = array_combine($lessonUsers['users_LOGIN'], $lessonUsers['users_LOGIN']); } else { $result = eF_getTableData("users", "name, surname, login"); $users = array(); foreach ($result as $user) { $users[$user['login']] = $user; } } } if ($users) { if (sizeof($tests) == 1) { $doneTests = EfrontStats::getDoneTestsPerTest(array_keys($users), current($tests), false, false, $lesson); } else { $doneTests = EfrontStats::getDoneTestsPerTest(array_keys($users), false, false, false, $lesson); } } foreach ($tests as $id) { $testInfo = array(); $test = new EfrontTest($id); //$unit = $test -> getUnit(); $testInfo['general']['id'] = $id; //$testInfo['general']['name'] = $unit -> offsetGet('name'); //$testInfo['general']['content_ID'] = $unit -> offsetGet('id'); $testInfo['general']['name'] = $test->test['name']; $testInfo['general']['content_ID'] = $test->test['content_ID']; $testInfo['general']['lesson_name'] = $lessonNames[$test->test['lessons_ID']]; $testInfo['general']['duration'] = $test->options['duration']; $testInfo['general']['duration_str'] = eF_convertIntervalToTime($test->options['duration']); $testInfo['general']['redoable'] = $test->options['redoable']; $testInfo['general']['redoable_str'] = $test->options['redoable'] >= 1 ? _YES : _NO; $testInfo['general']['onebyone'] = $test->options['onebyone']; $testInfo['general']['onebyone_str'] = $test->options['onebyone'] == 1 ? _YES : _NO; $testInfo['general']['answers'] = $test->options['answers']; $testInfo['general']['answers_str'] = $test->options['answers'] == 1 ? _YES : _NO; $testInfo['general']['description'] = $test->test['description']; //$testInfo['general']['timestamp'] = $unit -> offsetGet('timestamp'); //$testInfo['general']['timestamp_str'] = strftime('%d-%m-%Y, %H:%M:%S', $testInfo['general']['timestamp']); $testInfo['general']['scorm'] = 0; $testInfo['questions']['total'] = 0; $testInfo['questions']['raw_text'] = 0; $testInfo['questions']['multiple_one'] = 0; $testInfo['questions']['multiple_many'] = 0; $testInfo['questions']['true_false'] = 0; $testInfo['questions']['match'] = 0; $testInfo['questions']['empty_spaces'] = 0; $testInfo['questions']['drag_drop'] = 0; $testInfo['questions']['low'] = 0; $testInfo['questions']['medium'] = 0; $testInfo['questions']['high'] = 0; if (!empty($test->options['random_test'])) { $questions = $test->getQuestionsForRandomSolvedTests(true); } else { $questions = $test->getQuestions(true); } foreach ($questions as $question) { $testInfo['questions']['total']++; $testInfo['questions'][$question->question['type']]++; $testInfo['questions'][$question->question['difficulty']]++; } //@todo: Compatibility status with old versions, need to change $testInfo['done'] = array(); // Create results score categories if ($categories) { $testInfo['score_categories'] = array(); $step = 100 / $categories; for ($i = 0; $i < $categories; $i++) { $testInfo['score_categories'][$i] = array("from" => $i * $step, "to" => ($i + 1) * $step, "count" => 0); if ($i == $categories - 1) { $testInfo['score_categories'][$i]["to"] = 100; } } } foreach ($doneTests[$id] as $user => $done) { foreach ($done as $key => $dt) { // Check that this $dt refers to a test occurence - and not average scores etc if (eF_checkParameter($key, "id") && ($show_all || $dt['archive'] == 0) && $dt['status'] != 'incomplete' && $dt['status'] != '') { $done_test = array('id' => $done['active_score'], 'users_LOGIN' => $dt['users_LOGIN'], 'name' => $users[$dt['users_LOGIN']]['name'], 'surname' => $users[$dt['users_LOGIN']]['surname'], 'score' => $dt['score'], 'active_score' => $done['active_score'], 'active_test_id' => $done['active_test_id'], 'timestamp' => $dt['time_end'], 'mastery_score' => $dt['mastery_score'], 'status' => $dt['status']); $testInfo['done'][] = $done_test; // Get the user's score in the correct stats category if ($categories) { $stat_cat = $dt['score'] / $step; $testInfo['score_categories'][$stat_cat >= $categories ? $categories - 1 : $stat_cat]["count"]++; } } } } // Create results score categories if ($categories) { $doneTestsCount = sizeof($testInfo['done']); $sum_count = $doneTestsCount; // counts how many users have score equal or above each score_category if ($sum_count > 0) { foreach ($testInfo['score_categories'] as $key => $score) { $testInfo['score_categories'][$key]['percent'] = round(100 * ($testInfo['score_categories'][$key]['count'] / $doneTestsCount), 2); $testInfo['score_categories'][$key]['sum_count'] = $sum_count; $testInfo['score_categories'][$key]['sum_count_percent'] = round(100 * ($sum_count / $doneTestsCount), 2); $sum_count -= $testInfo['score_categories'][$key]['count']; } } } $testsInfo[$id] = $testInfo; } return $testsInfo; }
/** * Handle AJAX actions * * This function is used to perform the necessary ajax actions, * that may be used in tests * <br/>Example: * <code> * $result = eF_getTableData("completed_tests", "*", "id=".$_GET['show_solved_test']); * $showTest = unserialize($result[0]['test']); * $status = $showTest -> getStatus($result[0]['users_LOGIN']); * $testString = $showTest -> toHTMLQuickForm(new HTML_Quickform(), false, true, true); * $testString = $showTest -> toHTMLSolved($testString, true); * if (isset($_GET['ajax'])) { * $showTest -> handleAjaxActions(); * } * </code> * * @since 3.5.2 * @access public */ public function handleAjaxActions() { try { if (isset($_GET['test_score'])) { if (mb_strpos($_GET['test_score'], ",") !== false) { $_GET['test_score'] = str_replace(",", ".", $_GET['test_score']); } if (is_numeric($_GET['test_score']) && $_GET['test_score'] <= 100 && $_GET['test_score'] >= 0) { $this->completedTest['score'] = $_GET['test_score']; foreach ($this->questions as $id => $question) { if ($question->pending) { $this->questions[$id]->pending = 0; $this->questions[$id]->score = $this->completedTest['score']; } } if ($this->test['mastery_score'] && $this->test['mastery_score'] > $this->completedTest['score']) { $this->completedTest['status'] = 'failed'; } else { if ($this->test['mastery_score'] && $this->test['mastery_score'] <= $this->completedTest['score']) { $this->completedTest['status'] = 'passed'; } } $this->completedTest['pending'] = 0; $this->save(); $result = eF_getTableData("completed_tests", "archive", "id=" . $this->completedTest['id']); if (!$result[0]['archive']) { $testUser = EfrontUserFactory::factory($this->completedTest['login']); if ($this->completedTest['status'] == 'failed') { $testUser->setSeenUnit($this->test['content_ID'], $this->test['lessons_ID'], 0); } else { $testUser->setSeenUnit($this->test['content_ID'], $this->test['lessons_ID'], 1); } } echo $this->completedTest['status']; } else { throw new EfrontTestException(_INVALIDSCORE . ': ' . $_GET['test_score'], EfrontTestException::INVALID_SCORE); } exit; } else { if (isset($_GET['test_feedback'])) { $this->completedTest['feedback'] = $_GET['test_feedback']; $this->save(); echo $_GET['test_feedback']; exit; } else { if (isset($_GET['redo_test']) && eF_checkParameter($_GET['redo_test'], 'id')) { $result = eF_getTableData("completed_tests", "tests_ID, users_LOGIN", "id=" . $_GET['redo_test']); $test = new EfrontTest($result[0]['tests_ID']); $test->redo($result[0]['users_LOGIN']); exit; } else { if (isset($_GET['redo_wrong_test']) && eF_checkParameter($_GET['redo_wrong_test'], 'id')) { $result = eF_getTableData("completed_tests", "tests_ID, users_LOGIN", "id=" . $_GET['redo_wrong_test']); $test = new EfrontTest($result[0]['tests_ID']); $test->redoOnlyWrong($result[0]['users_LOGIN']); exit; } else { if (isset($_GET['delete_done_test'])) { if (isset($_GET['all'])) { $this->undo($this->completedTest['login']); //eF_deleteTableData("completed_tests", "users_LOGIN='******'login']."' and tests_ID=".$this -> completedTest['testsId']); } else { $this->undo($this->completedTest['login'], $this->completedTest['id']); //eF_deleteTableData("completed_tests", "id=".$this -> completedTest['id']); } exit; } else { if (isset($_GET['question_score'])) { if (mb_strpos($_GET['question_score'], ",") !== false) { $_GET['question_score'] = str_replace(",", ".", $_GET['question_score']); } if (in_array($_GET['question'], array_keys($this->questions))) { if (is_numeric($_GET['question_score']) && $_GET['question_score'] <= 100 && $_GET['question_score'] >= 0) { $this->questions[$_GET['question']]->score = $_GET['question_score']; $this->questions[$_GET['question']]->scoreInTest = round($_GET['question_score'] * $this->getQuestionWeight($_GET['question']), 3); $this->questions[$_GET['question']]->pending = 0; $score = 0; foreach ($this->questions as $question) { $this->completedTest['scoreInTest'][$question->question['id']] = $question->scoreInTest; $score += $question->scoreInTest; } $this->completedTest['score'] = round($score, 2); $testUser = EfrontUserFactory::factory($this->completedTest['login']); if ($this->test['mastery_score'] && $this->test['mastery_score'] > $this->completedTest['score']) { if ($this->getPotentialScore() < $this->test['mastery_score']) { $this->completedTest['status'] = 'failed'; $flag = 0; //$testUser -> setSeenUnit($this -> test['content_ID'], $this -> test['lessons_ID'], 0); } } else { if ($this->test['mastery_score'] && $this->test['mastery_score'] <= $this->completedTest['score']) { $this->completedTest['status'] = 'passed'; $flag = 1; //$testUser -> setSeenUnit($this -> test['content_ID'], $this -> test['lessons_ID'], 1); } } $this->completedTest['pending'] = 0; foreach ($this->getQuestions(true) as $question) { if ($question->pending) { $this->completedTest['pending'] = 1; } } try { $lesson = new EfrontLesson($this->test['lessons_ID']); $lesson_name = $lesson->lesson['name']; } catch (EfrontLessonException $e) { $lesson_name = _SKILLGAPTESTS; } if (!$this->completedTest['pending']) { EfrontEvent::triggerEvent(array("type" => EfrontEvent::TEST_MARKED, "users_LOGIN" => $this->completedTest['login'], "lessons_ID" => $this->test['lessons_ID'], "lessons_name" => $lesson_name, "entity_ID" => $this->test['id'], "entity_name" => $this->test['name'])); } if ($this->completedTest['status'] == 'failed' && $this->completedTest['pending'] != 1) { EfrontEvent::triggerEvent(array("type" => EfrontEvent::TEST_FAILURE, "users_LOGIN" => $this->completedTest['login'], "lessons_ID" => $this->test['lessons_ID'], "lessons_name" => $lesson_name, "entity_ID" => $this->test['id'], "entity_name" => $this->test['name'])); } $this->save(); $testUser->setSeenUnit($this->test['content_ID'], $this->test['lessons_ID'], $flag); echo json_encode($this->completedTest); } else { throw new EfrontTestException(_INVALIDSCORE . ': ' . $_GET['test_score'], EfrontTestException::INVALID_SCORE); } } else { throw new EfrontTestException(_INVALIDID . ': ' . $_GET['question'], EfrontTestException::QUESTION_NOT_EXISTS); } exit; } else { if (isset($_GET['question_feedback'])) { if (in_array($_GET['question'], array_keys($this->questions))) { $this->questions[$_GET['question']]->feedback = $_GET['question_feedback']; $this->save(); echo $_GET['question_feedback']; } else { throw new EfrontTestException(_INVALIDID . ': ' . $_GET['question'], EfrontTestException::QUESTION_NOT_EXISTS); } exit; } else { if (isset($_GET['delete_file'])) { $file = new EfrontFile($_GET['delete_file']); $testDirectory = $this->getDirectory(); if (strpos($file['path'], $testDirectory['path']) !== false) { $file->delete(); } exit; } } } } } } } } } catch (Exception $e) { handleAjaxExceptions($e); } }
} if ($_GET['ctg'] != 'feedback') { $messageString = _SUCCESFULLYMODIFIEDTEST; } else { $messageString = _SUCCESFULLYMODIFIEDFEEDBACK; } EfrontCache::getInstance()->deleteCache("content_tree:{$_SESSION['s_lessons_ID']}"); eF_redirect("" . ltrim(basename($_SERVER['PHP_SELF']), "/") . "?ctg=" . $_GET['ctg'] . "&from_unit=" . $_GET['from_unit'] . "&message=" . urlencode($messageString) . "&message_type=success"); } else { $contentFields = array('data' => '', 'name' => $values['name'], 'lessons_ID' => $currentLesson->lesson['id'], 'ctg_type' => $_GET['ctg'], 'active' => 1, 'timestamp' => time(), 'parent_content_ID' => $values['parent_content']); $testFields = array('active' => 1, 'lessons_ID' => isset($currentLesson->lesson['id']) ? $currentLesson->lesson['id'] : 0, 'content_ID' => $test_content_ID, 'description' => applyEditorOffset($values['description']), 'options' => serialize($testOptions), 'name' => $values['name'], 'publish' => $values['publish'], 'keep_best' => $values['keep_best'], 'mastery_score' => $values['mastery_score'] ? $values['mastery_score'] : 0); if (!$skillgap_tests) { $newUnit = $currentContent->insertNode($contentFields); $newTest = EfrontTest::createTest($newUnit, $testFields); } else { $newTest = EfrontTest::createTest(false, $testFields); } // If the new test comes from an existing one we should also copy its questions... if ($_GET['edit_test']) { $testQuestions = $currentTest->getQuestions(); $newTest->addQuestions($testQuestions); // ... and its users if it is a skillgap test if ($skillgap_tests) { $testUsers = eF_getTableDataFlat("users_to_skillgap_tests", "users_LOGIN", "tests_ID = '" . $_GET['edit_test'] . "'"); $fields = array(); foreach ($testUsers as $entry) { $fields[] = array('tests_ID' => $newTest->test['id'], 'users_LOGIN' => $entry['useres_LOGIN']); } if (sizeof($fields) > 0) { eF_insertTableDataMultiple("users_to_skillgap_tests", $fields); //$insertString = "('" . $newTest->test['id'] . "', '" . implode("'),('" . $newTest -> test['id'] . "', '", $testUsers['users_LOGIN']) . "')";
$showTest = new EfrontTest($_GET['view_unit'], true); if (isset($_GET['show_all'])) { $showTest->options['random_pool'] = false; $showTest->options['onebyone'] = 0; } if (isset($_GET['preview_correct']) && $_SESSION['s_lesson_user_type'] != 'student') { $showTest->preview_correct = true; } if (isset($_GET['print'])) { $testString = $showTest->toHTML($showTest->toHTMLQuickForm(), false, true); } else { $testString = $showTest->toHTML($showTest->toHTMLQuickForm(), false); } $smarty->assign("T_TEST", $testString); } else { $test = new EfrontTest($currentUnit['id'], true); $status = $test->getStatus($currentUser, $_GET['show_solved_test']); $form = new HTML_QuickForm("test_form", "post", basename($_SERVER['PHP_SELF']) . '?view_unit=' . $_GET['view_unit'], "", 'onsubmit = "$(\'submit_test\').disabled=true;"', true); switch ($status['status']) { case 'incomplete': if (!($testInstance = unserialize($status['completedTest']['test']))) { throw new EfrontTestException(_TESTCORRUPTEDASKRESETEXECUTION, EfrontTestException::CORRUPTED_TEST); } if ($testInstance->time['pause'] && isset($_GET['resume'])) { $testInstance->time['pause'] = 0; $testInstance->time['resume'] = time(); //unset($testInstance -> currentQuestion); $testInstance->save(); } $remainingTime = $testInstance->options['duration'] - $testInstance->time['spent'] - (time() - $testInstance->time['resume']); $nocache = false;
if ($_GET['postAjaxRequest']) { header("HTTP/1.0 500 "); echo $e->getMessage() . ' (' . $e->getCode() . ')'; } else { throw $e; } } if ($_GET['postAjaxRequest']) { exit; } $message = _SKILLGAPTESTRESULTSREMOVEDFROMUSERTHETESTCANBEREPEATED; $message_type = 'success'; } if (isset($_GET['ajax']) && isset($_GET['redo_test']) && eF_checkParameter($_GET['redo_test'], 'id')) { $result = eF_getTableData("completed_tests", "tests_ID, users_LOGIN", "id=" . $_GET['redo_test']); $test = new EfrontTest($result[0]['tests_ID']); $test->redo($result[0]['users_LOGIN']); //$testInstance -> handleAjaxActions(); } //Get the list of valid tests for the current lesson. if (isset($currentContent)) { $result = eF_getTableData("tests t, content c", "t.*", "t.content_ID=c.id and c.lessons_ID=" . $currentLesson->lesson['id']); foreach ($result as $value) { $allTests[$value['content_ID']] = $value; } $testsIterator = new EfrontTestsFilterIterator(new EfrontNodeFilterIterator(new RecursiveIteratorIterator(new RecursiveArrayIterator($currentContent->tree), RecursiveIteratorIterator::SELF_FIRST), array('active' => 1))); foreach ($testsIterator as $key => $value) { if ($value['ctg_type'] == 'tests') { $availableTests[$key] = $allTests[$key]['id']; } }