Esempio n. 1
0
 /**
  * return the number of question of a category id in a test
  * input : test_id, category_id
  * return : integer
  * hubert.borderiou 07-04-2011
  */
 public static function getNumberOfQuestionsInCategoryForTest($exercise_id, $category_id)
 {
     $number_questions_in_category = 0;
     $exercise = new Exercise();
     $exercise->read($exercise_id);
     $question_list = $exercise->getQuestionList();
     // the array given by selectQuestionList start at indice 1 and not at indice 0 !!! ? ? ?
     foreach ($question_list as $question_id) {
         $category_in_question = Testcategory::getCategoryForQuestion($question_id);
         if (in_array($category_id, $category_in_question)) {
             $number_questions_in_category++;
         }
     }
     return $number_questions_in_category;
 }
Esempio n. 2
0
} elseif ($filter == 'orphan') {
    $filterCondition = " AND REQ.`exerciseId` IS NULL ";
} else {
    if (!is_null($categoryId)) {
        $filterCondition = "AND id_category='" . (int) $categoryId . "' ";
    } else {
        $filterCondition = "";
    }
}
//-- prepare query
if (!is_null($categoryId)) {
    // Filter on categories
    $sql = "SELECT Q.`id`, Q.`title`, Q.`type`, Q.`id_category`\n              FROM `" . $tbl_quiz_question . "` AS Q\n              WHERE 1 = 1\n             " . $filterCondition . "\n          GROUP BY Q.`id`\n          ORDER BY Q.`title`, Q.`id`";
} else {
    if (!is_null($exId)) {
        $questionList = $exercise->getQuestionList();
        if (is_array($questionList) && !empty($questionList)) {
            foreach ($questionList as $aQuestion) {
                $questionIdList[] = $aQuestion['id'];
            }
            $questionCondition = " AND Q.`id` NOT IN (" . implode(', ', array_map('intval', $questionIdList)) . ") ";
        } else {
            $questionCondition = "";
        }
        // TODO probably need to adapt query with a left join on rel_exercise_question for filter
        $sql = "SELECT Q.`id`, Q.`title`, Q.`type`, Q.`id_category`\n              FROM `" . $tbl_quiz_question . "` AS Q\n              LEFT JOIN `" . $tbl_quiz_rel_exercise_question . "` AS REQ\n              ON REQ.`questionId` = Q.`id`\n              WHERE 1 = 1\n             " . $questionCondition . "\n             " . $filterCondition . "\n          GROUP BY Q.`id`\n          ORDER BY Q.`title`, Q.`id`";
    } else {
        $sql = "SELECT Q.`id`, Q.`title`, Q.`type`, Q.`id_category`\n              FROM `" . $tbl_quiz_question . "` AS Q\n              LEFT JOIN `" . $tbl_quiz_rel_exercise_question . "` AS REQ\n              ON REQ.`questionId` = Q.`id`\n              WHERE 1 = 1\n             " . $filterCondition . "\n          GROUP BY Q.`id`\n          ORDER BY Q.`title`, Q.`id`";
    }
}
// get list
Esempio n. 3
0
    $toolTitle['subTitle'] = $exercise->getTitle();
    ClaroBreadCrumbs::getInstance()->prepend(get_lang('Exercises'), Url::Contextualize(get_module_url('CLQWZ') . '/exercise.php'));
    ClaroBreadCrumbs::getInstance()->setCurrent($nameTools, Url::Contextualize('./edit_exercise.php?exId=' . $exId));
}
CssLoader::getInstance()->load('exercise', 'screen');
$out = '';
$out .= claro_html_tool_title($toolTitle, null, $cmdList);
// dialog box if required
$out .= $dialogBox->render();
if ($displayForm) {
    // -- edit form
    $display = new ModuleTemplate('CLQWZ', 'exercise_form.tpl.php');
    $display->assign('exId', $exId);
    $display->assign('data', $form);
    $display->assign('relayContext', claro_form_relay_context());
    $display->assign('questionCount', count($exercise->getQuestionList()));
    $out .= $display->render();
} else {
    //-- exercise settings
    $detailsDisplay = new ModuleTemplate('CLQWZ', 'exercise_details.tpl.php');
    $detailsDisplay->assign('exercise', $exercise);
    $detailsDisplay->assign('dateTimeFormatLong', $dateTimeFormatLong);
    $detailsDisplay->assign('questionList', $exercise->getQuestionList());
    $detailsDisplay->assign('localizedQuestionType', get_localized_question_type());
    $out .= $detailsDisplay->render();
    $qlistDisplay = new ModuleTemplate('CLQWZ', 'question_list.tpl.php');
    $qlistDisplay->assign('exId', $exercise->getId());
    $qlistDisplay->assign('questionList', $exercise->getQuestionList());
    $qlistDisplay->assign('context', 'exercise');
    $qlistDisplay->assign('localizedQuestionType', get_localized_question_type());
    $out .= $qlistDisplay->render();
Esempio n. 4
0
function export_exercise_tracking($exId)
{
    $exercise = new Exercise();
    if (!$exercise->load($exId)) {
        return "";
    }
    $questionList = $exercise->getQuestionList();
    $exerciseCsv = '';
    foreach ($questionList as $question) {
        $exerciseCsv .= export_question_tracking($question['id'], $exId);
    }
    return $exerciseCsv;
}
Esempio n. 5
0
    /**
     * Create files (quiz) needed in the export of this module
     *
     * @copyright   (c) 2001-2011, Universite catholique de Louvain (UCL)
     * @param int $quizId id of the Quiz
     * @param object $item item of the path
     * @param string $destDir path when the files need to be copied
     * @param int $deepness deepness of the destinationd directory
     * @return boolean
     */
    public function prepareFiles($quizId, &$item, $destDir, $deepness)
    {
        $completionThresold = $item->getCompletionThreshold();
        if (empty($completionThresold)) {
            $completionThresold = 50;
        }
        $quizId = (int) $quizId;
        $quiz = new Exercise();
        if (!$quiz->load($quizId)) {
            $this->error[] = get_lang('Unable to load the exercise');
            return false;
        }
        $deep = '';
        if ($deepness) {
            for ($i = $deepness; $i > 0; $i--) {
                $deep .= ' ../';
            }
        }
        // Generate standard page header
        $pageHeader = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
    <head>
    <title>' . $quiz->getTitle() . '</title>
    <meta http-equiv="expires" content="Tue, 05 DEC 2000 07:00:00 GMT">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Content-Type" content="text/HTML; charset=' . get_locale('charset') . '"  />

    <link rel="stylesheet" type="text/css" href="' . $deep . get_conf('claro_stylesheet') . '/main.css" media="screen, projection, tv" />
    <script language="javascript" type="text/javascript" src="' . $deep . 'js/jquery.js"></script>
    <script language="javascript" type="text/javascript" src="' . $deep . 'js/claroline.js"></script>
    <script language="javascript" type="text/javascript" src="' . $deep . 'js/claroline.ui.js"></script>

    <script language="javascript" type="text/javascript" src="' . $deep . 'js/APIWrapper.js"></script>
    <script language="javascript" type="text/javascript" src="' . $deep . 'js/connector13.js"></script>
    <script language="javascript" type="text/javascript" src="' . $deep . 'js/scores.js"></script>
    </head>
    ' . "\n";
        $pageBody = '<body onload="loadPage()">
    <div id="claroBody"><form id="quiz">
    <table width="100%" border="0" cellpadding="1" cellspacing="0" class="claroTable">' . "\n";
        // Get the question list
        $questionList = $quiz->getQuestionList();
        $questionCount = count($questionList);
        // Keep track of raw scores (ponderation) for each question
        $questionPonderationList = array();
        // Keep track of correct texts for fill-in type questions
        // TODO La variable $fillAnswerList n'apparaît qu'une fois
        $fillAnswerList = array();
        // Display each question
        $questionCount = 0;
        foreach ($questionList as $question) {
            // Update question number
            $questionCount++;
            // read the question, abort on error
            $scormQuestion = new ScormQuestion();
            if (!$scormQuestion->load($question['id'])) {
                $this->error[] = get_lang('Unable to load exercise\'s question');
                return false;
            }
            $questionPonderationList[] = $scormQuestion->getGrade();
            $pageBody .= '<thead>' . "\n" . '<tr>' . "\n" . '<th>' . get_lang('Question') . ' ' . $questionCount . '</th>' . "\n" . '</tr>' . "\n" . '</thead>' . "\n";
            $pageBody .= '<tr>' . "\n" . '<td>' . "\n" . $scormQuestion->export() . "\n" . '</td>' . "\n" . '</tr>' . "\n";
        }
        $pageEnd = '
    <tr>
        <td align="center"><br /><input type="button" value="' . get_lang('Ok') . '" onclick="calcScore()" /></td>
    </tr>
    </table>
    </form>
    </div></body></html>' . "\n";
        /* Generate the javascript that'll calculate the score
         * We have the following variables to help us :
         * $idCounter : number of elements to check. their id are "scorm_XY"
         * $raw_to_pass : score (on 100) needed to pass the quiz
         * $fillAnswerList : a list of arrays (text, score) indexed on <input>'s names
         *
         */
        $pageHeader .= '
    <script type="text/javascript" language="javascript">
        var raw_to_pass = '******';
        var weighting = ' . array_sum($questionPonderationList) . ';
        var rawScore;
        var scoreCommited = false;
        var showScore = true;
        var fillAnswerList = new Array();' . "\n";
        // This is the actual code present in every exported exercise.
        // use claro_html_entity_decode in output to prevent double encoding errors with some languages...
        $pageHeader .= '

        function calcScore()
        {
            if( !scoreCommited )
            {
                rawScore = CalculateRawScore(document, ' . getIdCounter() . ', fillAnswerList);
                var score = Math.max(Math.round(rawScore * 100 / weighting), 0);
                var oldScore = doLMSGetValue("cmi.score.raw");
    
                doLMSSetValue("cmi.score.max", weighting);
                doLMSSetValue("cmi.score.min", 0);
    
                computeTime();
    
                if (score > oldScore) // Update only if score is better than the previous time.
                {
                    doLMSSetValue("cmi.raw", rawScore);
                }
                
                var oldStatus = doLMSGetValue( "cmi.completion_status" )
                if (score >= raw_to_pass)
                {
                    doLMSSetValue("cmi.completion_status", "completed");
                }
                else if (oldStatus != "completed" ) // If passed once, never mark it as failed.
                {
                    doLMSSetValue("cmi.completion_status", "failed");
                }
    
                doLMSCommit();
                doLMSFinish();
                scoreCommited = true;
                if(showScore) alert(\'' . clean_str_for_javascript(claro_html_entity_decode(get_lang('Score'))) . ' :\\n\' + rawScore + \'/\' + weighting );
            }
        }
    
    </script>
    ';
        // Construct the HTML file and save it.
        $filename = "quiz_" . $quizId . ".html";
        $pageContent = $pageHeader . $pageBody . $pageEnd;
        if (!($f = fopen($destDir . '/' . $filename, 'w'))) {
            $this->error = get_lang('Unable to create file : ') . $filename;
            return false;
        }
        fwrite($f, $pageContent);
        fclose($f);
        return true;
    }
Esempio n. 6
0
        /**
         * Exports an exercise as a SCO.
         * This method is intended to be called from the prepare method.
         *
         *@note There's a lot of nearly cut-and-paste from exercise.lib.php here
         *      because of some little differences...
         *      Perhaps something that could be refactorised ?
         *
         * @see prepare
         * @param $quizId The quiz
         * @param $raw_to_pass The needed score to attain
         * @return False on error, True if everything went well.
         * @author  Amand Tihon <*****@*****.**>
         */
        public function prepareQuiz($quizId, $raw_to_pass = 50)
        {
            global $claro_stylesheet;
            // those two variables are needed by display_attached_file()
            global $attachedFilePathWeb;
            global $attachedFilePathSys;
            $attachedFilePathWeb = 'Exercises';
            $attachedFilePathSys = $this->destDir . '/Exercises';
            // read the exercise
            $quiz = new Exercise();
            if (!$quiz->load($quizId)) {
                $this->error[] = get_lang('Unable to load the exercise');
                return false;
            }
            // Generate standard page header
            $pageHeader = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>' . $quiz->getTitle() . '</title>
    <meta http-equiv="expires" content="Tue, 05 DEC 2000 07:00:00 GMT">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Content-Type" content="text/HTML; charset=' . get_locale('charset') . '"  />

    <link rel="stylesheet" type="text/css" href="' . get_conf('claro_stylesheet') . '/main.css" media="screen, projection, tv" />
    <script language="javascript" type="text/javascript" src="jquery.js"></script>
    <script language="javascript" type="text/javascript" src="claroline.js"></script>
    <script language="javascript" type="text/javascript" src="claroline.ui.js"></script>

    <script language="javascript" type="text/javascript" src="APIWrapper.js"></script>
    <script language="javascript" type="text/javascript" src="scores.js"></script>
    ' . "\n";
            $pageBody = '<body onload="loadPage()">
        <div id="claroBody"><form id="quiz">
        <table width="100%" border="0" cellpadding="1" cellspacing="0" class="claroTable">' . "\n";
            // Get the question list
            $questionList = $quiz->getQuestionList();
            $questionCount = count($questionList);
            // Keep track of raw scores (ponderation) for each question
            $questionPonderationList = array();
            // Keep track of correct texts for fill-in type questions
            // TODO La variable $fillAnswerList n'appara�t qu'une fois
            $fillAnswerList = array();
            // Display each question
            $questionCount = 0;
            foreach ($questionList as $question) {
                // Update question number
                $questionCount++;
                // read the question, abort on error
                $scormQuestion = new ScormQuestion();
                if (!$scormQuestion->load($question['id'])) {
                    $this->error[] = get_lang('Unable to load exercise\'s question');
                    return false;
                }
                $questionPonderationList[] = $scormQuestion->getGrade();
                $pageBody .= '<tr class="headerX">' . "\n" . '<th>' . get_lang('Question') . ' ' . $questionCount . '</th>' . "\n" . '</tr>' . "\n";
                $pageBody .= '<tr>' . "\n" . '<td>' . "\n" . $scormQuestion->export() . "\n" . '</td>' . "\n" . '</tr>' . "\n";
                /*
                                if( !empty($scormQuestion->getAttachment()) )
                                {
                                    // copy the attached file
                                    if ( !claro_copy_file($this->srcDirExercise . '/' . $attachedFile, $this->destDir . '/Exercises') )
                                    {
                                        $this->error[] = get_lang('Unable to copy file : %filename', array ( '%filename' => $attachedFile  ));
                                        return false;
                                    }
                
                                    // Ok, if it was an mp3, we need to copy the flash mp3-player too.
                                    $extension=substr(strrchr($attachedFile, '.'), 1);
                                    if ( $extension == 'mp3')   $this->mp3Found = true;
                
                                    $pageBody .= '<tr><td colspan="2">' . display_attached_file($attachedFile) . '</td></tr>' . "\n";
                                }
                */
                /*
                 * Display the possible answers
                 */
                // End of the question
            }
            // foreach($questionList as $questionId)
            // No more questions, add the button.
            $pageEnd = '
                <tr>
                    <td align="center"><br /><input type="button" value="' . get_lang('Ok') . '" onclick="calcScore()" /></td>
                </tr>
                </table>
                </form>
                </div></body></html>' . "\n";
            /* Generate the javascript that'll calculate the score
             * We have the following variables to help us :
             * $idCounter : number of elements to check. their id are "scorm_XY"
             * $raw_to_pass : score (on 100) needed to pass the quiz
             * $fillAnswerList : a list of arrays (text, score) indexed on <input>'s names
             *
             */
            $pageHeader .= '
    <script type="text/javascript" language="javascript">
        var raw_to_pass = '******';
        var weighting = ' . array_sum($questionPonderationList) . ';
        var rawScore;
        var scoreCommited = false;
        var showScore = true;
        var fillAnswerList = new Array();' . "\n";
            // This is the actual code present in every exported exercise.
            // use claro_html_entity_decode in output to prevent double encoding errors with some languages...
            $pageHeader .= '

        function calcScore()
        {
            if( !scoreCommited )
            {
                rawScore = CalculateRawScore(document, ' . getIdCounter() . ', fillAnswerList);
                var score = Math.max(Math.round(rawScore * 100 / weighting), 0);
                var oldScore = doLMSGetValue("cmi.core.score.raw");

                doLMSSetValue("cmi.core.score.max", weighting);
                doLMSSetValue("cmi.core.score.min", 0);

                computeTime();

                if (score > oldScore) // Update only if score is better than the previous time.
                {
                    doLMSSetValue("cmi.core.score.raw", rawScore);
                }

                var mode = doLMSGetValue( "cmi.core.lesson_mode" );
                if ( mode != "review"  &&  mode != "browse" )
                {
                    var oldStatus = doLMSGetValue( "cmi.core.lesson_status" )
                    if (score >= raw_to_pass)
                    {
                        doLMSSetValue("cmi.core.lesson_status", "passed");
                    }
                    else if (oldStatus != "passed" ) // If passed once, never mark it as failed.
                    {
                        doLMSSetValue("cmi.core.lesson_status", "failed");
                    }
                }

                doLMSCommit();
                doLMSFinish();
                scoreCommited = true;
                if(showScore) alert(\'' . clean_str_for_javascript(claro_html_entity_decode(get_lang('Score'))) . ' :\\n\' + rawScore + \'/\' + weighting );
            }
        }
    
    </script>
    ';
            // Construct the HTML file and save it.
            $filename = "quiz_" . $quizId . ".html";
            $pageContent = $pageHeader . $pageBody . $pageEnd;
            if (!($f = fopen($this->destDir . '/' . $filename, 'w'))) {
                $this->error[] = get_lang('Unable to create file : ') . $filename;
                return false;
            }
            fwrite($f, $pageContent);
            fclose($f);
            // Went well.
            return True;
        }