/** * 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; }
$graph->label = _SCOREINUNIT; $graph->meanValueLabel = _SCOREINTEST; echo json_encode($graph); exit; } } catch (Exception $e) { handleAjaxExceptions($e); } } break; default: if (isset($_GET['confirm'])) { //The user specified himself the size of the test if ($test->options['user_configurable']) { //Get the size of the test, so that we can verify that the value specified is at most equal to it $test->getQuestions(); //This way the test's questions are populated, and we will be needing this information if (empty($test->options['random_test'])) { $test->options['random_pool'] && $test->options['random_pool'] <= sizeof($test->questions) ? $questionsNumber = $test->options['random_pool'] : ($questionsNumber = sizeof($test->questions)); } else { $questionsNumber = $test->getNumQuestionsForRandomTests(); } //Assigning the 'user_configurable' value to the 'random_pool' option gives us a test instance with the appropriate number of questions if (is_numeric($_GET['user_configurable']) && $_GET['user_configurable'] <= $questionsNumber && $_GET['user_configurable'] > 0) { $test->options['random_pool'] = $_GET['user_configurable']; } else { if (!isset($_GET['user_configurable']) || !$_GET['user_configurable']) { eF_redirect(basename($_SERVER['PHP_SELF']) . "?view_unit=" . $_GET['view_unit'] . '&message=' . urlencode(_MUSTSPECIFYQUESTIONNUMBER)); exit; } else { if ($_GET['user_configurable'] > $questionsNumber || $_GET['user_configurable'] <= 0) {
$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; } } } catch (Exception $e) { handleAjaxExceptions($e);
/** * 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; }
if ($configuration['math_content'] && $configuration['math_images']) { $loadScripts[] = 'ASCIIMath2Tex'; } elseif ($configuration['math_content']) { $loadScripts[] = 'ASCIIMathML'; } if (isset($_GET['edit_test'])) { $currentTest = new EfrontTest($_GET['edit_test']); if (!$skillgap_tests) { $currentUnit = new EfrontUnit($currentTest->test['content_ID']); $is_linked = $currentUnit['linked_to'] ? true : false; } if ($is_linked) { eF_redirect("" . ltrim(basename($_SERVER['PHP_SELF']), "/") . "?ctg=tests&message=" . urlencode(_LINKEDTESTSCANNOTBEEDITTED) . "&message_type=failure"); } if (!empty($currentTest->options['random_test']) && $_GET['random_test'] == 0) { $testQuestions = $currentTest->getQuestions(false, true); } else { $testQuestions = $currentTest->getQuestions(); } //if test contains a question from another lesson, display all lessons questions if (G_VERSIONTYPE != 'community') { #cpp#ifndef COMMUNITY if (G_VERSIONTYPE != 'standard') { #cpp#ifndef STANDARD if (EfrontUser::isOptionVisible('questions_pool') && !isset($_GET['showall'])) { $showAllFlag = false; foreach ($testQuestions as $key => $value) { if ($value['lessons_ID'] != $_SESSION['s_lessons_ID']) { $showAllFlag = true; } }
} //Default url for the file manager $url = basename($_SERVER['PHP_SELF']) . '?ctg=' . $_GET['ctg'] . '&' . (isset($_GET['edit_test']) ? 'edit_test=' . $_GET['edit_test'] : 'add_test=1'); $extraFileTools = array(array('image' => 'images/16x16/arrow_right.png', 'title' => _INSERTEDITOR, 'action' => 'insert_editor')); /**The file manager*/ include "file_manager.php"; //This page also needs an editor and ASCIIMathML $load_editor = true; if ($configuration['math_content'] && $configuration['math_images']) { $loadScripts[] = 'ASCIIMath2Tex'; } elseif ($configuration['math_content']) { $loadScripts[] = 'ASCIIMathML'; } if (isset($_GET['edit_test'])) { $currentTest = new EfrontTest($_GET['edit_test']); $testQuestions = $currentTest->getQuestions(); //if test contains a question from another lesson, display all lessons questions if (G_VERSIONTYPE != 'community') { #cpp#ifndef COMMUNITY if (G_VERSIONTYPE != 'standard') { #cpp#ifndef STANDARD if (EfrontUser::isOptionVisible('questions_pool') && !isset($_GET['showall'])) { $showAllFlag = false; foreach ($testQuestions as $key => $value) { if ($value['lessons_ID'] != $_SESSION['s_lessons_ID']) { $showAllFlag = true; } } if ($showAllFlag) { $_GET['showall'] = 1; }