Merge from 1.11.x

pull/3063/head
jmontoyaa 8 years ago
parent 259ed0ac9b
commit caacefb08c
  1. 21
      main/exercise/annotation_user.php
  2. 165
      main/exercise/answer.class.php
  3. 51
      main/exercise/calculated_answer.class.php
  4. 625
      main/exercise/exercise.class.php
  5. 99
      main/exercise/exercise_submit.php
  6. 141
      main/exercise/fill_blanks.class.php
  7. 220
      main/exercise/question.class.php
  8. 149
      main/exercise/question_pool.php
  9. 2
      main/inc/lib/api.lib.php
  10. 484
      main/inc/lib/exercise.lib.php
  11. 50
      main/inc/lib/exercise_show_functions.lib.php
  12. 89
      main/inc/lib/javascript/annotation/js/annotation.js
  13. 8
      main/inc/lib/javascript/ckeditor/config_js.php
  14. 15
      main/inc/lib/javascript/hotspot/js/hotspot.js
  15. 19
      main/inc/lib/javascript/pear/qfamsHandler.js

@ -1,17 +1,21 @@
<?php
/* For licensing terms, see /license.txt */
use ChamiloSession as Session;
session_cache_limiter("none");
session_cache_limiter('none');
require_once __DIR__.'/../inc/global.inc.php';
$questionId = isset($_GET['question_id']) ? intval($_GET['question_id']) : 0;
$exerciseId = isset($_GET['exe_id']) ? intval($_GET['exe_id']) : 0;
$questionId = isset($_GET['question_id']) ? (int) $_GET['question_id'] : 0;
$exerciseId = isset($_GET['exe_id']) ? (int) $_GET['exe_id'] : 0;
$courseId = isset($_GET['course_id']) ? (int) $_GET['course_id'] : 0;
$courseInfo = api_get_course_info_by_id($courseId);
if (empty($courseInfo)) {
return '';
}
$objQuestion = Question::read($questionId);
$documentPath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
$objQuestion = Question::read($questionId, $courseId);
$documentPath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/document';
$picturePath = $documentPath.'/images';
$pictureSize = getimagesize($picturePath.'/'.$objQuestion->getPictureFilename());
$pictureWidth = $pictureSize[0];
@ -34,10 +38,8 @@ $attemptList = Event::getAllExerciseEventByExeId($exerciseId);
if (!empty($attemptList) && isset($attemptList[$questionId])) {
$questionAttempt = $attemptList[$questionId][0];
if (!empty($questionAttempt['answer'])) {
$answers = explode('|', $questionAttempt['answer']);
foreach ($answers as $answer) {
$parts = explode(')(', $answer);
$type = array_shift($parts);
@ -45,7 +47,6 @@ if (!empty($attemptList) && isset($attemptList[$questionId])) {
switch ($type) {
case 'P':
$points = [];
foreach ($parts as $partPoint) {
$points[] = Geometry::decodePoint($partPoint);
}

@ -50,17 +50,17 @@ class Answer
* @param int $course_id
* @param Exercise $exercise
*/
public function __construct($questionId, $course_id = null, $exercise = null)
public function __construct($questionId, $course_id = 0, $exercise = null)
{
$this->questionId = intval($questionId);
$this->answer = array();
$this->correct = array();
$this->comment = array();
$this->weighting = array();
$this->position = array();
$this->hotspot_coordinates = array();
$this->hotspot_type = array();
$this->destination = array();
$this->answer = [];
$this->correct = [];
$this->comment = [];
$this->weighting = [];
$this->position = [];
$this->hotspot_coordinates = [];
$this->hotspot_type = [];
$this->destination = [];
// clears $new_* arrays
$this->cancel();
@ -96,15 +96,15 @@ class Answer
*/
public function cancel()
{
$this->new_answer = array();
$this->new_correct = array();
$this->new_comment = array();
$this->new_weighting = array();
$this->new_position = array();
$this->new_hotspot_coordinates = array();
$this->new_hotspot_type = array();
$this->new_answer = [];
$this->new_correct = [];
$this->new_comment = [];
$this->new_weighting = [];
$this->new_position = [];
$this->new_hotspot_coordinates = [];
$this->new_hotspot_type = [];
$this->new_nbrAnswers = 0;
$this->new_destination = array();
$this->new_destination = [];
}
/**
@ -166,12 +166,12 @@ class Answer
return [];
}
/**
* returns all answer ids from this question Id
*
* @author Yoselyn Castillo
* @return array - $id (answer ids)
*/
/**
* returns all answer ids from this question Id
*
* @author Yoselyn Castillo
* @return array - $id (answer ids)
*/
public function selectAnswerId()
{
$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
@ -182,7 +182,7 @@ class Answer
WHERE c_id = {$this->course_id} AND question_id ='".$questionId."'";
$result = Database::query($sql);
$id = array();
$id = [];
// while a record is found
if (Database::num_rows($result) > 0) {
while ($object = Database::fetch_array($result)) {
@ -345,6 +345,7 @@ class Answer
/**
* return array answer by id else return a bool
* @param integer $auto_id
* @return array
*/
public function selectAnswerByAutoId($auto_id)
{
@ -393,7 +394,7 @@ class Answer
*/
public function getAnswersList($decode = false)
{
$list = array();
$list = [];
for ($i = 1; $i <= $this->nbrAnswers; $i++) {
if (!empty($this->answer[$i])) {
//Avoid problems when parsing elements with accents
@ -410,7 +411,7 @@ class Answer
);
}
$list[] = array(
$list[] = [
'id' => $i,
'answer' => $this->answer[$i],
'comment' => $this->comment[$i],
@ -419,7 +420,7 @@ class Answer
'hotspot_type' => $this->hotspot_type[$i],
'correct' => $this->correct[$i],
'destination' => $this->destination[$i],
);
];
}
}
@ -433,7 +434,7 @@ class Answer
*/
public function getGradesList()
{
$list = array();
$list = [];
for ($i = 0; $i < $this->nbrAnswers; $i++) {
if (!empty($this->answer[$i])) {
$list[$i] = $this->weighting[$i];
@ -492,7 +493,7 @@ class Answer
*
* @author Olivier Brouckaert
* @param - integer $id - answer ID
* @param integer $id
* @return integer - answer weighting
*/
public function selectWeighting($id)
@ -582,8 +583,10 @@ class Answer
* @param string $weighting
* @param string $position
* @param string $destination
* @param string $hotspot_coordinates
* @param string $hotspot_type
* @param string $hotSpotCoordinates
* @param string $hotSpotType
*
* @return CQuizAnswer
*/
public function updateAnswers(
$iid,
@ -593,25 +596,31 @@ class Answer
$weighting,
$position,
$destination,
$hotspot_coordinates,
$hotspot_type
$hotSpotCoordinates,
$hotSpotType
) {
$em = Database::getManager();
/** @var CQuizAnswer $quizAnswer */
$quizAnswer = $em->find('ChamiloCourseBundle:CQuizAnswer', $iid);
$quizAnswer
->setAnswer($answer)
->setComment($comment)
->setCorrect($correct)
->setPonderation($weighting)
->setPosition($position)
->setDestination($destination)
->setHotspotCoordinates($hotspot_coordinates)
->setHotspotType($hotspot_type);
$em->merge($quizAnswer);
$em->flush();
if ($quizAnswer) {
$quizAnswer
->setAnswer($answer)
->setComment($comment)
->setCorrect($correct)
->setPonderation($weighting)
->setPosition($position)
->setDestination($destination)
->setHotspotCoordinates($hotSpotCoordinates)
->setHotspotType($hotSpotType);
$em->merge($quizAnswer);
$em->flush();
return $quizAnswer;
}
return false;
}
/**
@ -623,9 +632,9 @@ class Answer
{
$answerTable = Database::get_course_table(TABLE_QUIZ_ANSWER);
$em = Database::getManager();
$questionId = intval($this->questionId);
$questionId = (int) $this->questionId;
$c_id = $this->course['real_id'];
$courseId = $this->course['real_id'];
$correctList = [];
$answerList = [];
@ -645,7 +654,7 @@ class Answer
$quizAnswer = new CQuizAnswer();
$quizAnswer
->setIdAuto($autoId)
->setCId($c_id)
->setCId($courseId)
->setQuestionId($questionId)
->setAnswer($answer)
->setCorrect($correct)
@ -696,7 +705,6 @@ class Answer
// https://support.chamilo.org/issues/6558
// function updateAnswers already escape_string, error if we do it twice.
// Feed function updateAnswers with none escaped strings
$this->updateAnswers(
$iid,
$this->new_answer[$i],
@ -719,20 +727,39 @@ class Answer
$questionType = self::getQuestionType();
if ($questionType == DRAGGABLE) {
foreach ($this->new_correct as $value => $status) {
if (!empty($status)) {
$correct = $answerList[$status];
$myAutoId = $answerList[$value];
$sql = "UPDATE $answerTable
switch ($questionType) {
case MATCHING_DRAGGABLE:
foreach ($this->new_correct as $value => $status) {
if (!empty($status)) {
if (isset($answerList[$status])) {
$correct = $answerList[$status];
} else {
$correct = $status;
}
$myAutoId = $answerList[$value];
$sql = "UPDATE $answerTable
SET correct = '$correct'
WHERE
id_auto = $myAutoId
";
Database::query($sql);
Database::query($sql);
}
}
}
break;
case DRAGGABLE:
foreach ($this->new_correct as $value => $status) {
if (!empty($status)) {
$correct = $answerList[$status];
$myAutoId = $answerList[$value];
$sql = "UPDATE $answerTable
SET correct = '$correct'
WHERE
id_auto = $myAutoId
";
Database::query($sql);
}
}
break;
}
if (count($this->position) > $this->new_nbrAnswers) {
@ -778,7 +805,7 @@ class Answer
$course_info = $this->course;
}
$fixed_list = array();
$fixed_list = [];
$tableAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER);
if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE ||
@ -820,7 +847,7 @@ class Answer
$em = Database::getManager();
if (in_array($newQuestion->type, [MATCHING, MATCHING_DRAGGABLE])) {
$temp = array();
$temp = [];
for ($i = 1; $i <= $this->nbrAnswers; $i++) {
$answer = [
'id' => $this->id[$i],
@ -940,7 +967,7 @@ class Answer
if (in_array($newQuestion->type, [DRAGGABLE, MATCHING, MATCHING_DRAGGABLE])) {
$onlyAnswersFlip = array_flip($onlyAnswers);
foreach ($correctAnswers as $answer_id => $correct_answer) {
$params = array();
$params = [];
if (isset($allAnswers[$correct_answer]) &&
isset($onlyAnswersFlip[$allAnswers[$correct_answer]])
) {
@ -948,13 +975,13 @@ class Answer
Database::update(
$tableAnswer,
$params,
array(
'id = ? AND c_id = ? AND question_id = ? ' => array(
[
'id = ? AND c_id = ? AND question_id = ? ' => [
$answer_id,
$courseId,
$newQuestionId,
),
)
],
]
);
}
}
@ -986,9 +1013,11 @@ class Answer
public function isCorrectByAutoId($needle)
{
$key = 0;
foreach ($this->autoId as $autoIdKey => $autoId) {
if ($autoId == $needle) {
$key = $autoIdKey;
if (is_array($this->autoId)) {
foreach ($this->autoId as $autoIdKey => $autoId) {
if ($autoId == $needle) {
$key = $autoIdKey;
}
}
}

@ -30,7 +30,7 @@ class CalculatedAnswer extends Question
*/
public function createAnswersForm($form)
{
$defaults = array();
$defaults = [];
if (!empty($this->id)) {
$objAnswer = new Answer($this->id);
$preArray = explode('@@', $objAnswer->selectAnswer(1));
@ -122,15 +122,15 @@ class CalculatedAnswer extends Question
'html_editor',
'answer',
Display::return_icon('fill_field.png'),
array(
[
'id' => 'answer',
'onkeyup' => 'javascript: updateBlanks(this);',
),
array(
],
[
'ToolbarSet' => 'TestQuestionDescription',
'Width' => '100%',
'Height' => '350',
)
]
);
$form->addRule('answer', get_lang('GiveText'), 'required');
@ -142,11 +142,11 @@ class CalculatedAnswer extends Question
$notationListButton = Display::url(
get_lang('NotationList'),
api_get_path(WEB_CODE_PATH).'exercise/evalmathnotation.php',
array(
[
'class' => 'btn btn-info ajax',
'data-title' => get_lang('NotationList'),
'_target' => '_blank'
)
]
);
$form->addElement(
'label',
@ -154,12 +154,11 @@ class CalculatedAnswer extends Question
$notationListButton
);
$form->addElement('label', null, get_lang('FormulaExample'));
$form->addElement('text', 'formula', get_lang('Formula'), array('id' => 'formula'));
$form->addElement('text', 'formula', [get_lang('Formula'), get_lang('FormulaExample')], ['id' => 'formula']);
$form->addRule('formula', get_lang('GiveFormula'), 'required');
$form->addElement('text', 'weighting', get_lang('Weighting'), array('id' => 'weighting'));
$form->setDefaults(array('weighting' => '10'));
$form->addElement('text', 'weighting', get_lang('Weighting'), ['id' => 'weighting']);
$form->setDefaults(['weighting' => '10']);
$form->addElement('text', 'answerVariations', get_lang('AnswerVariations'));
$form->addRule(
@ -167,14 +166,14 @@ class CalculatedAnswer extends Question
get_lang('GiveAnswerVariations'),
'required'
);
$form->setDefaults(array('answerVariations' => '1'));
$form->setDefaults(['answerVariations' => '1']);
global $text;
// setting the save button here and not in the question class.php
$form->addButtonSave($text, 'submitQuestion');
if (!empty($this->id)) {
$form -> setDefaults($defaults);
$form->setDefaults($defaults);
} else {
if ($this->isContent == 1) {
$form->setDefaults($defaults);
@ -191,12 +190,12 @@ class CalculatedAnswer extends Question
$table = Database::get_course_table(TABLE_QUIZ_ANSWER);
Database::delete(
$table,
array(
'c_id = ? AND question_id = ?' => array(
[
'c_id = ? AND question_id = ?' => [
$this->course['real_id'],
$this->id
)
)
]
]
);
$answer = $form->getSubmitValue('answer');
$formula = $form->getSubmitValue('formula');
@ -213,7 +212,7 @@ class CalculatedAnswer extends Question
if ($nb > 0) {
for ($i = 0; $i < $nb; ++$i) {
$blankItem = $blanks[0][$i];
$replace = array("[", "]");
$replace = ["[", "]"];
$newBlankItem = str_replace($replace, "", $blankItem);
$newBlankItem = "[".trim($newBlankItem)."]";
// take random float values when one or both edge values have a decimal point
@ -236,10 +235,10 @@ class CalculatedAnswer extends Question
// Attach formula
$auxAnswer .= " [".$result."]@@".$formula;
}
$this->save();
$this->save($exercise);
$objAnswer = new Answer($this->id);
$objAnswer->createAnswer($auxAnswer, 1, '', $this->weighting, '');
$objAnswer->position = array();
$objAnswer->position = [];
$objAnswer->save();
}
}
@ -271,14 +270,14 @@ class CalculatedAnswer extends Question
$result = Database::select(
'question_id',
$table,
array(
'where' => array(
'question_id = ? AND c_id = ?' => array(
[
'where' => [
'question_id = ? AND c_id = ?' => [
$this->id,
$this->course['real_id']
)
)
)
]
]
]
);
return empty($result) ? false : true;

File diff suppressed because it is too large Load Diff

@ -37,11 +37,12 @@ $debug = false;
api_protect_course_script(true);
$origin = api_get_origin();
$is_allowedToEdit = api_is_allowed_to_edit(null, true);
$courseId = api_get_course_int_id();
$glossaryExtraTools = api_get_setting('show_glossary_in_extra_tools');
$showGlossary = in_array($glossaryExtraTools, array('true', 'exercise', 'exercise_and_lp'));
$showGlossary = in_array($glossaryExtraTools, ['true', 'exercise', 'exercise_and_lp']);
if ($origin == 'learnpath') {
$showGlossary = in_array($glossaryExtraTools, array('true', 'lp', 'exercise_and_lp'));
$showGlossary = in_array($glossaryExtraTools, ['true', 'lp', 'exercise_and_lp']);
}
if ($showGlossary) {
$htmlHeadXtra[] = '<script type="text/javascript" src="'.api_get_path(WEB_CODE_PATH).'glossary/glossary.js.php?add_ready=1&'.api_get_cidreq().'"></script>';
@ -110,7 +111,7 @@ if (api_is_allowed_to_edit(null, true) &&
$exerciseInSession = Session::read('objExercise');
if (!isset($exerciseInSession) || isset($exerciseInSession) && ($exerciseInSession->id != $_GET['exerciseId'])) {
// Construction of Exercise
$objExercise = new Exercise();
$objExercise = new Exercise($courseId);
Session::write('firstTime', true);
if ($debug) {
error_log('1. Setting the $objExercise variable');
@ -170,7 +171,7 @@ $templateName = $template->get_template('exercise/submit.js.tpl');
$htmlHeadXtra[] = $template->fetch($templateName);
$current_timestamp = time();
$myRemindList = array();
$myRemindList = [];
$time_control = false;
if ($objExercise->expired_time != 0) {
@ -220,7 +221,7 @@ if ($objExercise->selectAttempts() > 0) {
$last_attempt_info = $exercise_stat_info[$max_exe_id];
$attempt_html .= Display::div(
get_lang('Date').': '.api_get_local_time($last_attempt_info['exe_date']),
array('id' => '')
['id' => '']
);
$attempt_html .= Display::return_message(
@ -242,11 +243,11 @@ if ($objExercise->selectAttempts() > 0) {
$question_info = Question::read($question_id);
$attempt_html .= Display::div(
$question_info->question,
array('class' => 'question_title')
['class' => 'question_title']
);
$attempt_html .= Display::div(
get_lang('Score').' '.$marks,
array('id' => 'question_question_titlescore')
['id' => 'question_question_titlescore']
);
}
}
@ -257,7 +258,7 @@ if ($objExercise->selectAttempts() > 0) {
);
$attempt_html .= Display::div(
get_lang('YourTotalScore').' '.$score,
array('id' => 'question_score')
['id' => 'question_score']
);
} else {
$attempt_html .= Display::return_message(
@ -431,7 +432,7 @@ if (!isset($questionListInSession)) {
) {
$questionList = explode(',', $exercise_stat_info['data_tracking']);
}
Session::write('questionList', $questionList);
Session::write('questionList', $questionList);
if ($debug > 0) {
error_log('$_SESSION[questionList] was set');
@ -467,7 +468,7 @@ if ($debug) {
if ($reminder == 2 && empty($myRemindList)) {
if ($debug) {
error_log("6.2 calling the exercise_reminder.php ");
};
}
header('Location: exercise_reminder.php?'.$params);
exit;
}
@ -592,24 +593,28 @@ if ($formSent && isset($_POST)) {
// Initializing
if (!is_array($exerciseResult)) {
$exerciseResult = array();
$exerciseResultCoordinates = array();
$exerciseResult = [];
$exerciseResultCoordinates = [];
}
//Only for hotspot
if (!isset($choice) && isset($_REQUEST['hidden_hotspot_id'])) {
$hotspot_id = (int) ($_REQUEST['hidden_hotspot_id']);
$choice = array($hotspot_id => '');
$hotspot_id = (int) $_REQUEST['hidden_hotspot_id'];
$choice = [$hotspot_id => ''];
}
// if the user has answered at least one question
if (is_array($choice)) {
if ($debug) { error_log('9.1. $choice is an array '.print_r($choice, 1)); }
if ($debug) {
error_log('9.1. $choice is an array '.print_r($choice, 1));
}
// Also store hotspot spots in the session ($exerciseResultCoordinates
// will be stored in the session at the end of this script)
if (isset($_POST['hotspot'])) {
$exerciseResultCoordinates = $_POST['hotspot'];
if ($debug) { error_log('9.2. $_POST[hotspot] data '.print_r($exerciseResultCoordinates, 1)); }
if ($debug) {
error_log('9.2. $_POST[hotspot] data '.print_r($exerciseResultCoordinates, 1));
}
}
if ($objExercise->type == ALL_ON_ONE_PAGE) {
// $exerciseResult receives the content of the form.
@ -617,7 +622,7 @@ if ($formSent && isset($_POST)) {
$exerciseResult = $choice;
} else {
// gets the question ID from $choice. It is the key of the array
list ($key) = array_keys($choice);
list($key) = array_keys($choice);
// if the user didn't already answer this question
if (!isset($exerciseResult[$key])) {
// stores the user answer into the array
@ -643,7 +648,7 @@ if ($formSent && isset($_POST)) {
false,
false,
$objExercise->propagate_neg,
array()
[]
);
}
//END of saving and qualifying
@ -678,7 +683,7 @@ if ($formSent && isset($_POST)) {
$learnpath_item_view_id
);
if ($attempt_count >= $objExercise->selectAttempts()) {
echo Display :: return_message(
echo Display::return_message(
sprintf(get_lang('ReachedMaxAttempts'), $exercise_title, $objExercise->selectAttempts()),
'warning',
false
@ -686,7 +691,7 @@ if ($formSent && isset($_POST)) {
if ($origin != 'learnpath') {
//so we are not in learnpath tool
echo '</div>'; //End glossary div
Display :: display_footer();
Display::display_footer();
} else {
echo '</body></html>';
}
@ -702,7 +707,9 @@ if ($formSent && isset($_POST)) {
exit;
}
} else {
if ($debug) { error_log('10. Redirecting to exercise_submit.php'); }
if ($debug) {
error_log('10. Redirecting to exercise_submit.php');
}
header("Location: exercise_submit.php?".api_get_cidreq()."&exerciseId=$exerciseId");
exit;
}
@ -729,8 +736,8 @@ if (is_null($current_question)) {
}
if ($question_count != 0) {
if (($objExercise->type == ALL_ON_ONE_PAGE ||
$current_question > $question_count)
if ($objExercise->type == ALL_ON_ONE_PAGE ||
$current_question > $question_count
) {
if (api_is_allowed_to_session_edit()) {
// goes to the script that will show the result of the exercise
@ -789,17 +796,17 @@ if ($question_count != 0) {
}
if (api_is_in_gradebook()) {
$interbreadcrumb[] = array(
$interbreadcrumb[] = [
'url' => Category::getUrl(),
'name' => get_lang('ToolGradebook')
);
];
}
$interbreadcrumb[] = array(
$interbreadcrumb[] = [
"url" => "exercise.php?".api_get_cidreq(),
"name" => get_lang('Exercises')
);
$interbreadcrumb[] = array("url" => "#", "name" => $objExercise->selectTitle(true));
];
$interbreadcrumb[] = ["url" => "#", "name" => $objExercise->selectTitle(true)];
if ($origin != 'learnpath') { //so we are not in learnpath tool
if (!api_is_allowed_to_session_edit()) {
@ -808,7 +815,7 @@ if ($origin != 'learnpath') { //so we are not in learnpath tool
);
}
Display :: display_header(null, 'Exercises');
Display::display_header(null, 'Exercises');
} else {
$htmlHeadXtra[] = "
<style>
@ -877,7 +884,7 @@ if ($limit_time_exists) {
'warning'
);
if ($origin != 'learnpath') {
Display :: display_footer();
Display::display_footer();
}
exit;
} else {
@ -985,7 +992,7 @@ if ($objExercise->review_answers) {
if (!empty($error)) {
echo Display::return_message($error, 'error', false);
} else {
if (!empty ($exercise_sound)) {
if (!empty($exercise_sound)) {
echo "<a href=\"../document/download.php?doc_url=%2Faudio%2F".Security::remove_XSS($exercise_sound)."\" target=\"_blank\">", "<img src=\"../img/sound.gif\" border=\"0\" align=\"absmiddle\" alt=", get_lang('Sound')."\" /></a>";
}
// Get number of hotspot questions for javascript validation
@ -1031,7 +1038,7 @@ if (!empty($error)) {
saveImage.src = \'' . Display::return_icon(
'save.png',
get_lang('Saved'),
array(),
[],
ICON_SIZE_SMALL,
false,
true
@ -1131,7 +1138,7 @@ if (!empty($error)) {
} else {
url = "exercise_submit.php?'.$params.'&num='.$current_question.'&remind_question_id='.$remind_question_id.'";
}
//$("#save_for_now_"+question_id).html(\'' . Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL).'\');
//$("#save_for_now_"+question_id).html(\'' . Display::return_icon('save.png', get_lang('Saved'), [], ICON_SIZE_SMALL).'\');
window.location = url;
}
@ -1171,9 +1178,9 @@ if (!empty($error)) {
data: "'.$params.'&type=simple&question_id="+question_id+"&"+my_choice+"&"+hotspot+"&"+remind_list,
success: function(return_value) {
if (return_value == "ok") {
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL).'\');
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('save.png', get_lang('Saved'), [], ICON_SIZE_SMALL).'\');
} else if (return_value == "error") {
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('error.png', get_lang('Error'), array(), ICON_SIZE_SMALL).'\');
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('error.png', get_lang('Error'), [], ICON_SIZE_SMALL).'\');
} else if (return_value == "one_per_page") {
var url = "";
if ('.$reminder.' == 1 ) {
@ -1188,13 +1195,13 @@ if (!empty($error)) {
url = url_extra;
}
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('save.png', get_lang('Saved'), array(), ICON_SIZE_SMALL).'\');
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('save.png', get_lang('Saved'), [], ICON_SIZE_SMALL).'\');
window.location = url;
}
},
error: function() {
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('error.png', get_lang('Error'), array(), ICON_SIZE_SMALL).'\');
$("#save_for_now_"+question_id).html(\'' . Display::return_icon('error.png', get_lang('Error'), [], ICON_SIZE_SMALL).'\');
}
});
}
@ -1253,7 +1260,7 @@ if (!empty($error)) {
}
</script>';
echo '<form id="exercise_form" method="post" action="'.api_get_self().'?'.api_get_cidreq().'&reminder='.$reminder.'&autocomplete=off&&exerciseId='.$exerciseId.'" name="frm_exercise" '.$onsubmit.'>
echo '<form id="exercise_form" method="post" action="'.api_get_self().'?'.api_get_cidreq().'&reminder='.$reminder.'&autocomplete=off&exerciseId='.$exerciseId.'" name="frm_exercise" '.$onsubmit.'>
<input type="hidden" name="formSent" value="1" />
<input type="hidden" name="exerciseId" value="'.$exerciseId.'" />
<input type="hidden" name="num" value="'.$current_question.'" id="num_current_id" />
@ -1304,7 +1311,6 @@ if (!empty($error)) {
}
$user_choice = null;
if (isset($attempt_list[$questionId])) {
$user_choice = $attempt_list[$questionId];
} elseif ($objExercise->saveCorrectAnswers) {
@ -1330,7 +1336,7 @@ if (!empty($error)) {
$exerciseActions = '';
$is_remind_on = false;
$attributes = array('id' =>'remind_list['.$questionId.']');
$attributes = ['id' =>'remind_list['.$questionId.']'];
if (in_array($questionId, $remind_list)) {
$is_remind_on = true;
$attributes['checked'] = 1;
@ -1394,7 +1400,7 @@ if (!empty($error)) {
];
$exerciseActions .= Display::div(
implode(PHP_EOL, $button),
array('class'=>'exercise_save_now_button')
['class'=>'exercise_save_now_button']
);
break;
}
@ -1409,17 +1415,17 @@ if (!empty($error)) {
'',
$attributes
).get_lang('ReviewQuestionLater'),
array(
[
'class' => 'checkbox',
'for' => 'remind_list['.$questionId.']'
)
]
);
$exerciseActions .= Display::div(
$remind_question_div,
array('class' => 'exercise_save_now_button')
['class' => 'exercise_save_now_button']
);
}
echo Display::div($exerciseActions, array('class'=>'form-actions'));
echo Display::div($exerciseActions, ['class'=>'form-actions']);
echo '</div>';
$i++;
@ -1435,11 +1441,10 @@ if (!empty($error)) {
$questionId,
$current_question
);
echo Display::div($exerciseActions, array('class'=>'exercise_actions'));
echo Display::div($exerciseActions, ['class'=>'exercise_actions']);
echo '<br>';
}
echo '</form>';
}
if ($origin != 'learnpath') {

@ -44,8 +44,8 @@ class FillBlanks extends Question
}
// Take the complete string except after the last '::'
$defaults['answer'] = $listAnswersInfo['text'];
$defaults['select_separator'] = $listAnswersInfo['blankseparatornumber'];
$blankSeparatorNumber = $listAnswersInfo['blankseparatornumber'];
$defaults['select_separator'] = $listAnswersInfo['blank_separator_number'];
$blankSeparatorNumber = $listAnswersInfo['blank_separator_number'];
} else {
$defaults['answer'] = get_lang('DefaultTextInBlanks');
$defaults['select_separator'] = 0;
@ -55,18 +55,17 @@ class FillBlanks extends Question
$blankSeparatorStart = self::getStartSeparator($blankSeparatorNumber);
$blankSeparatorEnd = self::getEndSeparator($blankSeparatorNumber);
$setWeightAndSize = '';
if (isset($listAnswersInfo) && count($listAnswersInfo['tabweighting']) > 0) {
foreach ($listAnswersInfo['tabweighting'] as $i => $weighting) {
if (isset($listAnswersInfo) && count($listAnswersInfo['weighting']) > 0) {
foreach ($listAnswersInfo['weighting'] as $i => $weighting) {
$setWeightAndSize .= 'document.getElementById("weighting['.$i.']").value = "'.$weighting.'";';
}
foreach ($listAnswersInfo['tabinputsize'] as $i => $sizeOfInput) {
foreach ($listAnswersInfo['input_size'] as $i => $sizeOfInput) {
$setWeightAndSize .= 'document.getElementById("sizeofinput['.$i.']").value = "'.$sizeOfInput.'";';
$setWeightAndSize .= 'document.getElementById("samplesize['.$i.']").style.width = "'.$sizeOfInput.'px";';
}
}
echo '<script>
echo '<script>
var firstTime = true;
var originalOrder = new Array();
var blankSeparatorStart = "'.$blankSeparatorStart.'";
@ -519,7 +518,7 @@ class FillBlanks extends Question
$displayForStudent,
$inBlankNumber
) {
$inTabTeacherSolution = $listAnswersInfo['tabwords'];
$inTabTeacherSolution = $listAnswersInfo['words'];
$inTeacherSolution = $inTabTeacherSolution[$inBlankNumber];
switch (self::getFillTheBlankAnswerType($inTeacherSolution)) {
@ -716,20 +715,20 @@ class FillBlanks extends Question
*
* @return array of information about the answer
*/
public static function getAnswerInfo($userAnswer = "", $isStudentAnswer = false)
public static function getAnswerInfo($userAnswer = '', $isStudentAnswer = false)
{
$listAnswerResults = array();
$listAnswerResults = [];
$listAnswerResults['text'] = '';
$listAnswerResults['wordsCount'] = 0;
$listAnswerResults['tabwordsbracket'] = array();
$listAnswerResults['tabwords'] = array();
$listAnswerResults['tabweighting'] = array();
$listAnswerResults['tabinputsize'] = array();
$listAnswerResults['words_count'] = 0;
$listAnswerResults['words_with_bracket'] = [];
$listAnswerResults['words'] = [];
$listAnswerResults['weighting'] = [];
$listAnswerResults['input_size'] = [];
$listAnswerResults['switchable'] = '';
$listAnswerResults['studentanswer'] = array();
$listAnswerResults['studentscore'] = array();
$listAnswerResults['blankseparatornumber'] = 0;
$listDoubleColon = array();
$listAnswerResults['student_answer'] = [];
$listAnswerResults['student_score'] = [];
$listAnswerResults['blank_separator_number'] = 0;
$listDoubleColon = [];
api_preg_match("/(.*)::(.*)$/s", $userAnswer, $listResult);
@ -741,7 +740,7 @@ class FillBlanks extends Question
$listDoubleColon[] = $listResult[2];
}
$listAnswerResults['systemstring'] = $listDoubleColon[1];
$listAnswerResults['system_string'] = $listDoubleColon[1];
// Make sure we only take the last bit to find special marks
$listArobaseSplit = explode('@', $listDoubleColon[1]);
@ -768,27 +767,27 @@ class FillBlanks extends Question
}
$listAnswerResults['text'] = $listDoubleColon[0];
$listAnswerResults['tabweighting'] = $listWeightings;
$listAnswerResults['tabinputsize'] = $listSizeOfInput;
$listAnswerResults['weighting'] = $listWeightings;
$listAnswerResults['input_size'] = $listSizeOfInput;
$listAnswerResults['switchable'] = $listArobaseSplit[1];
$listAnswerResults['blankseparatorstart'] = self::getStartSeparator($blankSeparatorNumber);
$listAnswerResults['blankseparatorend'] = self::getEndSeparator($blankSeparatorNumber);
$listAnswerResults['blankseparatornumber'] = $blankSeparatorNumber;
$listAnswerResults['blank_separator_start'] = self::getStartSeparator($blankSeparatorNumber);
$listAnswerResults['blank_separator_end'] = self::getEndSeparator($blankSeparatorNumber);
$listAnswerResults['blank_separator_number'] = $blankSeparatorNumber;
$blankCharStart = self::getStartSeparator($blankSeparatorNumber);
$blankCharEnd = self::getEndSeparator($blankSeparatorNumber);
$blankCharStartForRegexp = self::escapeForRegexp($blankCharStart);
$blankCharEndForRegexp = self::escapeForRegexp($blankCharEnd);
// get all blanks words
$listAnswerResults['wordsCount'] = api_preg_match_all(
// Get all blanks words
$listAnswerResults['words_count'] = api_preg_match_all(
'/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/',
$listDoubleColon[0],
$listWords
);
if ($listAnswerResults['wordsCount'] > 0) {
$listAnswerResults['tabwordsbracket'] = $listWords[0];
if ($listAnswerResults['words_count'] > 0) {
$listAnswerResults['words_with_bracket'] = $listWords[0];
// remove [ and ] in string
array_walk(
$listWords[0],
@ -801,7 +800,7 @@ class FillBlanks extends Question
},
[$blankCharStart, $blankCharEnd]
);
$listAnswerResults['tabwords'] = $listWords[0];
$listAnswerResults['words'] = $listWords[0];
}
// Get all common words
@ -816,28 +815,28 @@ class FillBlanks extends Question
$listBrackets = [];
$listWords = [];
if ($isStudentAnswer) {
for ($i = 0; $i < count($listAnswerResults['tabwords']); $i++) {
$listBrackets[] = $listAnswerResults['tabwordsbracket'][$i];
$listWords[] = $listAnswerResults['tabwords'][$i];
if ($i + 1 < count($listAnswerResults['tabwords'])) {
for ($i = 0; $i < count($listAnswerResults['words']); $i++) {
$listBrackets[] = $listAnswerResults['words_with_bracket'][$i];
$listWords[] = $listAnswerResults['words'][$i];
if ($i + 1 < count($listAnswerResults['words'])) {
// should always be
$i++;
}
$listAnswerResults['studentanswer'][] = $listAnswerResults['tabwords'][$i];
if ($i + 1 < count($listAnswerResults['tabwords'])) {
$listAnswerResults['student_answer'][] = $listAnswerResults['words'][$i];
if ($i + 1 < count($listAnswerResults['words'])) {
// should always be
$i++;
}
$listAnswerResults['studentscore'][] = $listAnswerResults['tabwords'][$i];
$listAnswerResults['student_score'][] = $listAnswerResults['words'][$i];
}
$listAnswerResults['tabwords'] = $listWords;
$listAnswerResults['tabwordsbracket'] = $listBrackets;
$listAnswerResults['words'] = $listWords;
$listAnswerResults['words_with_bracket'] = $listBrackets;
// if we are in student view, we've got 3 times :::::: for common words
$commonWords = api_preg_replace("/::::::/", "::", $commonWords);
}
$listAnswerResults['commonwords'] = explode("::", $commonWords);
$listAnswerResults['common_words'] = explode("::", $commonWords);
return $listAnswerResults;
}
@ -907,23 +906,23 @@ class FillBlanks extends Question
$tabAnswer = self::getAnswerInfo($data['answer'], true);
// for each bracket to find in this question
foreach ($tabAnswer['studentanswer'] as $bracketNumber => $studentAnswer) {
if ($tabAnswer['studentanswer'][$bracketNumber] != '') {
foreach ($tabAnswer['student_answer'] as $bracketNumber => $studentAnswer) {
if ($tabAnswer['student_answer'][$bracketNumber] != '') {
// student has answered this bracket, cool
switch (self::getFillTheBlankAnswerType($tabAnswer['tabwords'][$bracketNumber])) {
switch (self::getFillTheBlankAnswerType($tabAnswer['words'][$bracketNumber])) {
case self::FILL_THE_BLANK_MENU:
// get the indice of the choosen answer in the menu
// we know that the right answer is the first entry of the menu, ie 0
// (remember, menu entries are shuffled when taking the test)
$tabUserResult[$data['user_id']][$bracketNumber] = self::getFillTheBlankMenuAnswerNum(
$tabAnswer['tabwords'][$bracketNumber],
$tabAnswer['studentanswer'][$bracketNumber]
$tabAnswer['words'][$bracketNumber],
$tabAnswer['student_answer'][$bracketNumber]
);
break;
default:
if (self::isGoodStudentAnswer(
$tabAnswer['studentanswer'][$bracketNumber],
$tabAnswer['tabwords'][$bracketNumber]
if (self::isStudentAnswerGood(
$tabAnswer['student_answer'][$bracketNumber],
$tabAnswer['words'][$bracketNumber]
)
) {
$tabUserResult[$data['user_id']][$bracketNumber] = 0; // right answer
@ -980,20 +979,20 @@ class FillBlanks extends Question
*/
public static function getAnswerInStudentAttempt($listWithStudentAnswer)
{
$separatorStart = $listWithStudentAnswer['blankseparatorstart'];
$separatorEnd = $listWithStudentAnswer['blankseparatorend'];
$separatorStart = $listWithStudentAnswer['blank_separator_start'];
$separatorEnd = $listWithStudentAnswer['blank_separator_end'];
// lets rebuild the sentence with [correct answer][student answer][answer is correct]
$result = '';
for ($i = 0; $i < count($listWithStudentAnswer['commonwords']) - 1; $i++) {
$result .= $listWithStudentAnswer['commonwords'][$i];
$result .= $listWithStudentAnswer['tabwordsbracket'][$i];
$result .= $separatorStart.$listWithStudentAnswer['studentanswer'][$i].$separatorEnd;
$result .= $separatorStart.$listWithStudentAnswer['studentscore'][$i].$separatorEnd;
for ($i = 0; $i < count($listWithStudentAnswer['common_words']) - 1; $i++) {
$result .= $listWithStudentAnswer['common_words'][$i];
$result .= $listWithStudentAnswer['words_with_bracket'][$i];
$result .= $separatorStart.$listWithStudentAnswer['student_answer'][$i].$separatorEnd;
$result .= $separatorStart.$listWithStudentAnswer['student_score'][$i].$separatorEnd;
}
$result .= $listWithStudentAnswer['commonwords'][$i];
$result .= $listWithStudentAnswer['common_words'][$i];
$result .= "::";
// add the system string
$result .= $listWithStudentAnswer['systemstring'];
$result .= $listWithStudentAnswer['system_string'];
return $result;
}
@ -1181,19 +1180,19 @@ class FillBlanks extends Question
// rebuild the answer with good HTML style
// this is the student answer, right or wrong
for ($i = 0; $i < count($listStudentAnswerInfo['studentanswer']); $i++) {
if ($listStudentAnswerInfo['studentscore'][$i] == 1) {
$listStudentAnswerInfo['studentanswer'][$i] = self::getHtmlRightAnswer(
$listStudentAnswerInfo['studentanswer'][$i],
$listStudentAnswerInfo['tabwords'][$i],
for ($i = 0; $i < count($listStudentAnswerInfo['student_answer']); $i++) {
if ($listStudentAnswerInfo['student_score'][$i] == 1) {
$listStudentAnswerInfo['student_answer'][$i] = self::getHtmlRightAnswer(
$listStudentAnswerInfo['student_answer'][$i],
$listStudentAnswerInfo['words'][$i],
$feedbackType,
$resultsDisabled,
$showTotalScoreAndUserChoices
);
} else {
$listStudentAnswerInfo['studentanswer'][$i] = self::getHtmlWrongAnswer(
$listStudentAnswerInfo['studentanswer'][$i],
$listStudentAnswerInfo['tabwords'][$i],
$listStudentAnswerInfo['student_answer'][$i] = self::getHtmlWrongAnswer(
$listStudentAnswerInfo['student_answer'][$i],
$listStudentAnswerInfo['words'][$i],
$feedbackType,
$resultsDisabled,
$showTotalScoreAndUserChoices
@ -1202,13 +1201,13 @@ class FillBlanks extends Question
}
// rebuild the sentence with student answer inserted
for ($i = 0; $i < count($listStudentAnswerInfo['commonwords']); $i++) {
$result .= isset($listStudentAnswerInfo['commonwords'][$i]) ? $listStudentAnswerInfo['commonwords'][$i] : '';
$result .= isset($listStudentAnswerInfo['studentanswer'][$i]) ? $listStudentAnswerInfo['studentanswer'][$i] : '';
for ($i = 0; $i < count($listStudentAnswerInfo['common_words']); $i++) {
$result .= isset($listStudentAnswerInfo['common_words'][$i]) ? $listStudentAnswerInfo['common_words'][$i] : '';
$result .= isset($listStudentAnswerInfo['student_answer'][$i]) ? $listStudentAnswerInfo['student_answer'][$i] : '';
}
// the last common word (should be </p>)
$result .= isset($listStudentAnswerInfo['commonwords'][$i]) ? $listStudentAnswerInfo['commonwords'][$i] : '';
$result .= isset($listStudentAnswerInfo['common_words'][$i]) ? $listStudentAnswerInfo['common_words'][$i] : '';
return $result;
}
@ -1352,8 +1351,8 @@ class FillBlanks extends Question
public static function isCorrect($answerText)
{
$answerInfo = self::getAnswerInfo($answerText, true);
$correctAnswerList = $answerInfo['tabwords'];
$studentAnswer = $answerInfo['studentanswer'];
$correctAnswerList = $answerInfo['words'];
$studentAnswer = $answerInfo['student_answer'];
$isCorrect = true;
foreach ($correctAnswerList as $i => $correctAnswer) {

@ -37,31 +37,31 @@ abstract class Question
public $questionTypeWithFeedback;
public $extra;
public $export = false;
public static $questionTypes = array(
UNIQUE_ANSWER => array('unique_answer.class.php', 'UniqueAnswer'),
MULTIPLE_ANSWER => array('multiple_answer.class.php', 'MultipleAnswer'),
FILL_IN_BLANKS => array('fill_blanks.class.php', 'FillBlanks'),
MATCHING => array('matching.class.php', 'Matching'),
FREE_ANSWER => array('freeanswer.class.php', 'FreeAnswer'),
ORAL_EXPRESSION => array('oral_expression.class.php', 'OralExpression'),
HOT_SPOT => array('hotspot.class.php', 'HotSpot'),
HOT_SPOT_DELINEATION => array('hotspot.class.php', 'HotspotDelineation'),
MULTIPLE_ANSWER_COMBINATION => array('multiple_answer_combination.class.php', 'MultipleAnswerCombination'),
UNIQUE_ANSWER_NO_OPTION => array('unique_answer_no_option.class.php', 'UniqueAnswerNoOption'),
MULTIPLE_ANSWER_TRUE_FALSE => array('multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'),
MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE => array(
public static $questionTypes = [
UNIQUE_ANSWER => ['unique_answer.class.php', 'UniqueAnswer'],
MULTIPLE_ANSWER => ['multiple_answer.class.php', 'MultipleAnswer'],
FILL_IN_BLANKS => ['fill_blanks.class.php', 'FillBlanks'],
MATCHING => ['matching.class.php', 'Matching'],
FREE_ANSWER => ['freeanswer.class.php', 'FreeAnswer'],
ORAL_EXPRESSION => ['oral_expression.class.php', 'OralExpression'],
HOT_SPOT => ['hotspot.class.php', 'HotSpot'],
HOT_SPOT_DELINEATION => ['hotspot.class.php', 'HotspotDelineation'],
MULTIPLE_ANSWER_COMBINATION => ['multiple_answer_combination.class.php', 'MultipleAnswerCombination'],
UNIQUE_ANSWER_NO_OPTION => ['unique_answer_no_option.class.php', 'UniqueAnswerNoOption'],
MULTIPLE_ANSWER_TRUE_FALSE => ['multiple_answer_true_false.class.php', 'MultipleAnswerTrueFalse'],
MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE => [
'multiple_answer_combination_true_false.class.php',
'MultipleAnswerCombinationTrueFalse'
),
GLOBAL_MULTIPLE_ANSWER => array('global_multiple_answer.class.php', 'GlobalMultipleAnswer'),
CALCULATED_ANSWER => array('calculated_answer.class.php', 'CalculatedAnswer'),
],
GLOBAL_MULTIPLE_ANSWER => ['global_multiple_answer.class.php', 'GlobalMultipleAnswer'],
CALCULATED_ANSWER => ['calculated_answer.class.php', 'CalculatedAnswer'],
UNIQUE_ANSWER_IMAGE => ['UniqueAnswerImage.php', 'UniqueAnswerImage'],
DRAGGABLE => ['Draggable.php', 'Draggable'],
MATCHING_DRAGGABLE => ['MatchingDraggable.php', 'MatchingDraggable'],
//MEDIA_QUESTION => array('media_question.class.php' , 'MediaQuestion')
ANNOTATION => ['Annotation.php', 'Annotation'],
READING_COMPREHENSION => ['ReadingComprehension.php', 'ReadingComprehension']
);
];
/**
* constructor of the class
@ -81,9 +81,9 @@ abstract class Question
// This variable is used when loading an exercise like an scenario with
// an special hotspot: final_overlap, final_missing, final_excess
$this->extra = '';
$this->exerciseList = array();
$this->exerciseList = [];
$this->course = api_get_course_info();
$this->category_list = array();
$this->category_list = [];
$this->parent_id = 0;
// See BT#12611
$this->questionTypeWithFeedback = [
@ -509,23 +509,26 @@ abstract class Question
* in this version, a question can only have 1 category
* if category is 0, then question has no category then delete the category entry
* @param int $categoryId
* @param int $courseId
* @return bool
*
* @author Hubert Borderiou 12-10-2011
*/
public function saveCategory($categoryId)
public function saveCategory($categoryId, $courseId = 0)
{
$courseId = api_get_course_int_id();
$courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
if (empty($courseId)) {
return false;
}
if ($categoryId <= 0) {
$this->deleteCategory();
$this->deleteCategory($courseId);
} else {
// update or add category for a question
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$categoryId = intval($categoryId);
$question_id = intval($this->id);
$categoryId = (int) $categoryId;
$question_id = (int) $this->id;
$sql = "SELECT count(*) AS nb FROM $table
WHERE
question_id = $question_id AND
@ -551,18 +554,25 @@ abstract class Question
/**
* @author hubert borderiou 12-10-2011
* @param int $courseId
* delete any category entry for question id
* delete the category for question
* @return bool
*/
public function deleteCategory()
public function deleteCategory($courseId = 0)
{
$courseId = empty($courseId) ? api_get_course_int_id() : (int) $courseId;
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$question_id = intval($this->id);
$questionId = (int) $this->id;
if (empty($courseId) || empty($questionId)) {
return false;
}
$sql = "DELETE FROM $table
WHERE
question_id = $question_id AND
c_id = ".api_get_course_int_id();
question_id = $questionId AND
c_id = ".$courseId;
Database::query($sql);
return true;
}
/**
@ -599,7 +609,7 @@ abstract class Question
*/
public function updateType($type)
{
$TBL_REPONSES = Database::get_course_table(TABLE_QUIZ_ANSWER);
$table = Database::get_course_table(TABLE_QUIZ_ANSWER);
$course_id = $this->course['real_id'];
if (empty($course_id)) {
@ -608,11 +618,11 @@ abstract class Question
// if we really change the type
if ($type != $this->type) {
// if we don't change from "unique answer" to "multiple answers" (or conversely)
if (!in_array($this->type, array(UNIQUE_ANSWER, MULTIPLE_ANSWER)) ||
!in_array($type, array(UNIQUE_ANSWER, MULTIPLE_ANSWER))
if (!in_array($this->type, [UNIQUE_ANSWER, MULTIPLE_ANSWER]) ||
!in_array($type, [UNIQUE_ANSWER, MULTIPLE_ANSWER])
) {
// removes old answers
$sql = "DELETE FROM $TBL_REPONSES
$sql = "DELETE FROM $table
WHERE c_id = $course_id AND question_id = ".intval($this->id);
Database::query($sql);
}
@ -1010,7 +1020,6 @@ abstract class Question
if ($exercise->questionFeedbackEnabled) {
$params['feedback'] = $this->feedback;
}
$this->id = Database::insert($TBL_QUESTIONS, $params);
if ($this->id) {
@ -1124,9 +1133,9 @@ abstract class Question
if (Database::num_rows($res) > 0 || $addQs) {
$di = new ChamiloIndexer();
if ($addQs) {
$question_exercises = array((int) $exerciseId);
$question_exercises = [(int) $exerciseId];
} else {
$question_exercises = array();
$question_exercises = [];
}
isset($_POST['language']) ? $lang = Database::escape_string($_POST['language']) : $lang = 'english';
$di->connectDb(null, null, $lang);
@ -1163,22 +1172,22 @@ abstract class Question
$ic_slide->addValue("title", $this->question);
$ic_slide->addCourseId($course_id);
$ic_slide->addToolId(TOOL_QUIZ);
$xapian_data = array(
$xapian_data = [
SE_COURSE_ID => $course_id,
SE_TOOL_ID => TOOL_QUIZ,
SE_DATA => array(
SE_DATA => [
'type' => SE_DOCTYPE_EXERCISE_QUESTION,
'exercise_ids' => $question_exercises,
'question_id' => (int) $this->id
),
],
SE_USER => (int) api_get_user_id(),
);
];
$ic_slide->xapian_data = serialize($xapian_data);
$ic_slide->addValue("content", $this->description);
//TODO: index answers, see also form validation on question_admin.inc.php
$di->remove_document((int) $se_ref['search_did']);
$di->remove_document($se_ref['search_did']);
$di->addChunk($ic_slide);
//index and return search engine document id
@ -1233,7 +1242,6 @@ abstract class Question
Database::query($sql);
}
}
}
}
}
@ -1389,7 +1397,6 @@ abstract class Question
api_get_user_id()
);
$this->removePicture();
} else {
// just removes the exercise from the list
$this->removeFromList($deleteFromEx);
@ -1412,17 +1419,17 @@ abstract class Question
* Duplicates the question
*
* @author Olivier Brouckaert
* @param array $course_info Course info of the destination course
* @param array $courseInfo Course info of the destination course
* @return false|string ID of the new question
*/
public function duplicate($course_info = [])
public function duplicate($courseInfo = [])
{
if (empty($course_info)) {
$course_info = $this->course;
} else {
$course_info = $course_info;
$courseInfo = empty($courseInfo) ? $this->course : $courseInfo;
if (empty($courseInfo)) {
return false;
}
$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
$questionTable = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_QUESTION_OPTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
$question = $this->question;
@ -1430,24 +1437,24 @@ abstract class Question
$weighting = $this->weighting;
$position = $this->position;
$type = $this->type;
$level = intval($this->level);
$level = (int) $this->level;
$extra = $this->extra;
// Using the same method used in the course copy to transform URLs
if ($this->course['id'] != $course_info['id']) {
if ($this->course['id'] != $courseInfo['id']) {
$description = DocumentManager::replaceUrlWithNewCourseCode(
$description,
$this->course['code'],
$course_info['id']
$courseInfo['id']
);
$question = DocumentManager::replaceUrlWithNewCourseCode(
$question,
$this->course['code'],
$course_info['id']
$courseInfo['id']
);
}
$course_id = $course_info['real_id'];
$course_id = $courseInfo['real_id'];
// Read the source options
$options = self::readQuestionOption($this->id, $this->course['real_id']);
@ -1463,10 +1470,10 @@ abstract class Question
'level' => $level,
'extra' => $extra
];
$newQuestionId = Database::insert($TBL_QUESTIONS, $params);
$newQuestionId = Database::insert($questionTable, $params);
if ($newQuestionId) {
$sql = "UPDATE $TBL_QUESTIONS
$sql = "UPDATE $questionTable
SET id = iid
WHERE iid = $newQuestionId";
Database::query($sql);
@ -1489,7 +1496,7 @@ abstract class Question
}
// Duplicates the picture of the hotspot
$this->exportPicture($newQuestionId, $course_info);
$this->exportPicture($newQuestionId, $courseInfo);
}
return $newQuestionId;
@ -1591,10 +1598,10 @@ abstract class Question
$form->addElement('hidden', 'answerType', $answerType);
// html editor
$editorConfig = array(
$editorConfig = [
'ToolbarSet' => 'TestQuestionDescription',
'Height' => '150'
);
];
if (!api_is_allowed_to_edit(null, true)) {
$editorConfig['UserStatus'] = 'student';
@ -1637,7 +1644,7 @@ abstract class Question
switch ($this->type) {
case UNIQUE_ANSWER:
$buttonGroup = array();
$buttonGroup = [];
$buttonGroup[] = $form->addButtonSave(
$text,
'submitQuestion',
@ -1656,7 +1663,7 @@ abstract class Question
$form->addGroup($buttonGroup);
break;
case MULTIPLE_ANSWER:
$buttonGroup = array();
$buttonGroup = [];
$buttonGroup[] = $form->addButtonSave(
$text,
'submitQuestion',
@ -1712,9 +1719,8 @@ abstract class Question
}
}
// default values
$defaults = array();
$defaults = [];
$defaults['questionName'] = $this->question;
$defaults['questionDescription'] = $this->description;
$defaults['questionLevel'] = $this->level;
@ -1790,10 +1796,10 @@ abstract class Question
if ($feedback_type == 1) {
//2. but if it is a feedback DIRECT we only show the UNIQUE_ANSWER type that is currently available
$question_type_custom_list = array(
$question_type_custom_list = [
UNIQUE_ANSWER => self::$questionTypes[UNIQUE_ANSWER],
HOT_SPOT_DELINEATION => self::$questionTypes[HOT_SPOT_DELINEATION]
);
];
} else {
unset($question_type_custom_list[HOT_SPOT_DELINEATION]);
}
@ -1887,12 +1893,12 @@ abstract class Question
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
Database::delete(
$table,
array(
'c_id = ? AND question_id = ?' => array(
[
'c_id = ? AND question_id = ?' => [
$course_id,
$question_id
)
)
]
]
);
}
@ -1908,7 +1914,7 @@ abstract class Question
$result = Database::update(
$table,
$params,
array('c_id = ? AND id = ?' => array($course_id, $id))
['c_id = ? AND id = ?' => [$course_id, $id]]
);
return $result;
}
@ -1924,15 +1930,15 @@ abstract class Question
$result = Database::select(
'*',
$table,
array(
'where' => array(
'c_id = ? AND question_id = ?' => array(
[
'where' => [
'c_id = ? AND question_id = ?' => [
$course_id,
$question_id
)
),
]
],
'order' => 'id ASC'
)
]
);
return $result;
@ -1982,12 +1988,14 @@ abstract class Question
}
// display question category, if any
$header = TestCategory::returnCategoryAndTitle($this->id);
$header = '';
if ($exercise->display_category_name) {
$header = TestCategory::returnCategoryAndTitle($this->id);
}
$show_media = null;
if ($show_media) {
$header .= $this->show_media_content();
}
// ofaj
$scoreCurrent = [
'used' => $score['score'],
'missing' => $score['weight']
@ -1998,7 +2006,7 @@ abstract class Question
// Do not show the description (the text to read) if the question is of type READING_COMPREHENSION
$header .= Display::div(
$this->description,
array('class' => 'question_description')
['class' => 'question_description']
);
} else {
if ($score['pass'] == true) {
@ -2114,7 +2122,7 @@ abstract class Question
$img = $explanation = null;
eval('$img = '.$tabQuestionList[$type][1].'::$typePicture;');
eval('$explanation = get_lang('.$tabQuestionList[$type][1].'::$explanationLangVar);');
return array($img, $explanation);
return [$img, $explanation];
}
/**
@ -2124,29 +2132,29 @@ abstract class Question
*
* @return array
*/
static function get_course_medias(
public static function get_course_medias(
$course_id,
$start = 0,
$limit = 100,
$sidx = "question",
$sord = "ASC",
$where_condition = array()
$where_condition = []
) {
$table_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
$default_where = array(
'c_id = ? AND parent_id = 0 AND type = ?' => array(
$default_where = [
'c_id = ? AND parent_id = 0 AND type = ?' => [
$course_id,
MEDIA_QUESTION
)
);
]
];
$result = Database::select(
'*',
$table_question,
array(
[
'limit' => " $start, $limit",
'where' => $default_where,
'order' => "$sidx $sord"
)
]
);
return $result;
@ -2158,20 +2166,20 @@ abstract class Question
*
* @return int
*/
static function get_count_course_medias($course_id)
public static function get_count_course_medias($course_id)
{
$table_question = Database::get_course_table(TABLE_QUIZ_QUESTION);
$result = Database::select(
'count(*) as count',
$table_question,
array(
'where' => array(
'c_id = ? AND parent_id = 0 AND type = ?' => array(
[
'where' => [
'c_id = ? AND parent_id = 0 AND type = ?' => [
$course_id,
MEDIA_QUESTION,
),
)
),
],
]
],
'first'
);
@ -2188,7 +2196,7 @@ abstract class Question
public static function prepare_course_media_select($course_id)
{
$medias = self::get_course_medias($course_id);
$media_list = array();
$media_list = [];
$media_list[0] = get_lang('NoMedia');
if (!empty($medias)) {
@ -2200,19 +2208,19 @@ abstract class Question
}
/**
* @return integer[]
* @return array
*/
public static function get_default_levels()
{
$select_level = array(
$levels = [
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5
);
];
return $select_level;
return $levels;
}
/**
@ -2237,20 +2245,20 @@ abstract class Question
*/
public function swapSimpleAnswerTypes()
{
$oppositeAnswers = array(
$oppositeAnswers = [
UNIQUE_ANSWER => MULTIPLE_ANSWER,
MULTIPLE_ANSWER => UNIQUE_ANSWER
);
];
$this->type = $oppositeAnswers[$this->type];
Database::update(
Database::get_course_table(TABLE_QUIZ_QUESTION),
array('type' => $this->type),
array('c_id = ? AND id = ?' => array($this->course['real_id'], $this->id))
['type' => $this->type],
['c_id = ? AND id = ?' => [$this->course['real_id'], $this->id]]
);
$answerClasses = array(
$answerClasses = [
UNIQUE_ANSWER => 'UniqueAnswer',
MULTIPLE_ANSWER => 'MultipleAnswer'
);
];
$swappedAnswer = new $answerClasses[$this->type];
foreach ($this as $key => $value) {
$swappedAnswer->$key = $value;

@ -48,13 +48,13 @@ if (empty($objExercise) && !empty($fromExercise)) {
}
$nameTools = get_lang('QuestionPool');
$interbreadcrumb[] = array("url" => "exercise.php", "name" => get_lang('Exercises'));
$interbreadcrumb[] = ["url" => "exercise.php?".api_get_cidreq(), "name" => get_lang('Exercises')];
if (!empty($objExercise)) {
$interbreadcrumb[] = array(
$interbreadcrumb[] = [
"url" => "admin.php?exerciseId=".$objExercise->id."&".api_get_cidreq(),
"name" => $objExercise->selectTitle(true)
);
];
}
// message to be displayed if actions successful
@ -62,15 +62,13 @@ $displayMessage = '';
if ($is_allowedToEdit) {
// Duplicating a Question
if (!isset($_POST['recup']) && $question_copy != 0 && isset($fromExercise)) {
$origin_course_id = intval($_GET['course_id']);
$origin_course_id = (int) $_GET['course_id'];
$origin_course_info = api_get_course_info_by_id($origin_course_id);
$current_course = api_get_course_info();
$old_question_id = $question_copy;
$current_course = api_get_course_info();
$old_question_id = $question_copy;
// Reading the source question
$old_question_obj = Question::read($old_question_id, $origin_course_id);
$courseId = $current_course['real_id'];
if ($old_question_obj) {
$old_question_obj->updateTitle(
$old_question_obj->selectTitle().' - '.get_lang('Copy')
@ -128,12 +126,10 @@ if ($is_allowedToEdit) {
Session::write('objExercise', $objExercise);
} elseif (isset($_POST['recup']) && is_array($_POST['recup']) && $fromExercise) {
$list_recup = $_POST['recup'];
foreach ($list_recup as $course_id => $question_data) {
$origin_course_id = intval($course_id);
$origin_course_id = (int) $course_id;
$origin_course_info = api_get_course_info_by_id($origin_course_id);
$current_course = api_get_course_info();
$current_course = api_get_course_info();
foreach ($question_data as $old_question_id) {
//Reading the source question
$old_question_obj = Question::read($old_question_id, $origin_course_id);
@ -142,10 +138,10 @@ if ($is_allowedToEdit) {
$old_question_obj->selectTitle().' - '.get_lang('Copy')
);
//Duplicating the source question, in the current course
// Duplicating the source question, in the current course
$new_id = $old_question_obj->duplicate($current_course);
//Reading new question
// Reading new question
$new_question_obj = Question::read($new_id);
$new_question_obj->addToList($fromExercise);
@ -172,10 +168,10 @@ if ($is_allowedToEdit) {
}
if (api_is_in_gradebook()) {
$interbreadcrumb[] = array(
$interbreadcrumb[] = [
'url' => Category::getUrl(),
'name' => get_lang('ToolGradebook')
);
];
}
// if admin of course
@ -184,7 +180,6 @@ if (!$is_allowedToEdit) {
}
$confirmYourChoice = addslashes(api_htmlentities(get_lang('ConfirmYourChoice'), ENT_QUOTES, $charset));
$htmlHeadXtra[] = "
<script>
function submit_form(obj) {
@ -241,10 +236,9 @@ echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
// Session list, if sessions are used.
$sessionList = SessionManager::get_sessions_by_user(api_get_user_id(), api_is_platform_admin());
$tabAttrParam = array('onchange' => 'submit_form(this)');
$tabAttrParam = ['onchange' => 'submit_form(this)'];
$labelFormRow = get_lang('Session');
$session_select_list = array();
$session_select_list = [];
foreach ($sessionList as $item) {
$session_select_list[$item['session_id']] = $item['session_name'];
}
@ -253,7 +247,7 @@ echo Display::form_row($labelFormRow, $select_session_html);
// Course list, get course list of session, or for course where user is admin
if (!empty($session_id) && $session_id != '-1' && !empty($sessionList)) {
$sessionInfo = array();
$sessionInfo = [];
foreach ($sessionList as $session) {
if ($session['session_id'] == $session_id) {
$sessionInfo = $session;
@ -270,19 +264,19 @@ if (!empty($session_id) && $session_id != '-1' && !empty($sessionList)) {
$courseInfo = api_get_course_info();
if (!empty($course_list)) {
if (!in_array($courseInfo['real_id'], $course_list)) {
$course_list = array_merge($course_list, array($courseInfo));
$course_list = array_merge($course_list, [$courseInfo]);
}
} else {
$course_list = array($courseInfo);
$course_list = [$courseInfo];
}
}
}
$course_select_list = array();
$course_select_list = [];
foreach ($course_list as $item) {
$courseItemId = $item['real_id'];
$courseInfo = api_get_course_info_by_id($courseItemId);
$course_select_list[$courseItemId] = "";
$course_select_list[$courseItemId] = '';
if ($courseItemId == api_get_course_int_id()) {
$course_select_list[$courseItemId] = ">&nbsp;&nbsp;&nbsp;&nbsp;";
}
@ -293,7 +287,7 @@ $select_course_html = Display::select(
'selected_course',
$course_select_list,
$selected_course,
array('onchange' => 'mark_course_id_changed(); submit_form(this);')
['onchange' => 'mark_course_id_changed(); submit_form(this);']
);
echo Display::form_row(get_lang('Course'), $select_course_html);
@ -327,13 +321,12 @@ $selectCourseCategory = Display::select(
'courseCategoryId',
$categoryList,
$courseCategoryId,
array('onchange' => 'submit_form(this);'),
['onchange' => 'submit_form(this);'],
false
);
echo Display::form_row(get_lang("QuestionCategory"), $selectCourseCategory);
echo Display::form_row(get_lang('QuestionCategory'), $selectCourseCategory);
// Get exercise list for this course
$exercise_list = ExerciseLib::get_all_exercises_for_course_id(
$course_info,
$session_id,
@ -341,12 +334,12 @@ $exercise_list = ExerciseLib::get_all_exercises_for_course_id(
false
);
//Exercise List
$my_exercise_list = array();
$my_exercise_list = [];
$my_exercise_list['0'] = get_lang('AllExercises');
$my_exercise_list['-1'] = get_lang('OrphanQuestions');
if (is_array($exercise_list)) {
foreach ($exercise_list as $row) {
$my_exercise_list[$row['id']] = "";
$my_exercise_list[$row['id']] = '';
if ($row['id'] == $fromExercise && $selected_course == api_get_course_int_id()) {
$my_exercise_list[$row['id']] = ">&nbsp;&nbsp;&nbsp;&nbsp;";
}
@ -361,14 +354,14 @@ $select_exercise_html = Display::select(
'exerciseId',
$my_exercise_list,
$exerciseId,
array('onchange' => 'mark_exercise_id_changed(); submit_form(this);'),
['onchange' => 'mark_exercise_id_changed(); submit_form(this);'],
false
);
echo Display::form_row(get_lang('Exercise'), $select_exercise_html);
// Difficulty list (only from 0 to 5)
$levels = array(
$levels = [
-1 => get_lang('All'),
0 => 0,
1 => 1,
@ -376,12 +369,12 @@ $levels = array(
3 => 3,
4 => 4,
5 => 5
);
];
$select_difficulty_html = Display::select(
'exerciseLevel',
$levels,
$exerciseLevel,
array('onchange' => 'submit_form(this);'),
['onchange' => 'submit_form(this);'],
false
);
echo Display::form_row(get_lang('Difficulty'), $select_difficulty_html);
@ -389,14 +382,14 @@ echo Display::form_row(get_lang('Difficulty'), $select_difficulty_html);
// Answer type
$question_list = Question::get_question_type_list();
$new_question_list = array();
$new_question_list = [];
$new_question_list['-1'] = get_lang('All');
if (!empty($_course)) {
$objExercise = new Exercise();
$objExercise->read($fromExercise);
foreach ($question_list as $key => $item) {
if ($objExercise->feedback_type == EXERCISE_FEEDBACK_TYPE_DIRECT) {
if (!in_array($key, array(HOT_SPOT_DELINEATION, UNIQUE_ANSWER))) {
if (!in_array($key, [HOT_SPOT_DELINEATION, UNIQUE_ANSWER])) {
continue;
}
$new_question_list[$key] = get_lang($item[1]);
@ -413,7 +406,7 @@ $select_answer_html = Display::select(
'answerType',
$new_question_list,
$answerType,
array('onchange' => 'submit_form(this);'),
['onchange' => 'submit_form(this);'],
false
);
@ -428,10 +421,9 @@ echo "<input type='hidden' id='exercise_id_changed' name='exercise_id_changed' v
<form method="post" action="<?php echo $url.'?'.api_get_cidreq().'&fromExercise='.$fromExercise; ?>" >
<?php
echo '<input type="hidden" name="course_id" value="'.$selected_course.'">';
$mainQuestionList = array();
$mainQuestionList = [];
// if we have selected an exercise in the list-box 'Filter'
if ($exerciseId > 0) {
$where = '';
$from = '';
@ -544,7 +536,7 @@ if ($exerciseId > 0) {
}
if (!empty($session_id) && $session_id != '-1') {
$mainQuestionList = array();
$mainQuestionList = [];
if (!empty($course_list)) {
foreach ($course_list as $course_item) {
$courseItemId = $course_item['real_id'];
@ -600,7 +592,7 @@ if ($exerciseId > 0) {
}
}
$question_row = array(
$question_row = [
'id' => $question_obj->id,
'question' => $question_obj->question,
'type' => $question_obj->type,
@ -608,7 +600,7 @@ if ($exerciseId > 0) {
'exercise_id' => $exercise['id'],
'exercise_name' => $exercise['title'],
'course_id' => $courseItemId,
);
];
$mainQuestionList[] = $question_row;
}
}
@ -618,10 +610,12 @@ if ($exerciseId > 0) {
}
}
} else {
if ($session_id == -1 or empty($session_id)) {
if ($session_id == -1 || empty($session_id)) {
$session_id = 0;
}
$sessionCondition = api_get_session_condition($session_id, true, 'q.session_id');
// All tests for the course selected, not in session
$sql = "SELECT DISTINCT qu.id, question, qu.type, level, q.session_id
FROM
@ -633,8 +627,8 @@ if ($exerciseId > 0) {
qu.c_id = $selected_course AND
qt.c_id = $selected_course AND
q.c_id = $selected_course AND
qu.id = qt.question_id AND
q.session_id = $session_id AND
qu.id = qt.question_id
$sessionCondition AND
q.id = qt.exercice_id $filter
ORDER BY session_id ASC";
$result = Database::query($sql);
@ -697,44 +691,44 @@ if ($fromExercise <= 0) {
}
}
// Display table
$header = array(
array(
$header = [
[
get_lang('QuestionUpperCaseFirstLetter'),
false,
array("style" => "text-align:center"),
["style" => "text-align:center"],
''
),
array(
],
[
get_lang('Type'),
false,
array("style" => "text-align:center"),
array("style" => "text-align:center"),
["style" => "text-align:center"],
["style" => "text-align:center"],
''
),
array(
],
[
get_lang('QuestionCategory'),
false,
array("style" => "text-align:center"),
array("style" => "text-align:center"),
["style" => "text-align:center"],
["style" => "text-align:center"],
''
),
array(
],
[
get_lang('Difficulty'),
false,
array("style" => "text-align:center"),
array("style" => "text-align:center"),
["style" => "text-align:center"],
["style" => "text-align:center"],
''
),
array(
],
[
$actionLabel,
false,
array("style" => "text-align:center"),
array("style" => "text-align:center"),
["style" => "text-align:center"],
["style" => "text-align:center"],
''
)
);
]
];
$data = array();
$data = [];
if (is_array($mainQuestionList)) {
foreach ($mainQuestionList as $question) {
@ -745,7 +739,7 @@ if (is_array($mainQuestionList)) {
}
$questionAdded[$question['question']] = $question;*/
$row = array();
$row = [];
// This function checks if the question can be read
$question_type = get_question_type_for_question(
@ -800,11 +794,11 @@ if (is_array($mainQuestionList)) {
}
}
Display :: display_sortable_table(
Display::display_sortable_table(
$header,
$data,
'',
array('per_page_default' => 999, 'per_page' => 999, 'page_nr' => 1)
['per_page_default' => 999, 'per_page' => 999, 'page_nr' => 1]
);
if (!$nbrQuestions) {
@ -900,12 +894,12 @@ function get_action_icon_for_question(
$res = "";
$getParams = "&selected_course=$in_selected_course&courseCategoryId=$in_courseCategoryId&exerciseId=$in_exercise_id&exerciseLevel=$in_exerciseLevel&answerType=$in_answerType&session_id=$in_session_id";
switch ($in_action) {
case "delete":
case 'delete':
$res = "<a href='".api_get_self()."?".api_get_cidreq().$getParams."&delete=$in_questionid' onclick='return confirm_your_choice()'>";
$res .= Display::return_icon("delete.png", get_lang('Delete'));
$res .= "</a>";
break;
case "edit":
case 'edit':
$res = get_a_tag_for_question(
1,
$from_exercise,
@ -915,20 +909,19 @@ function get_action_icon_for_question(
$in_session_id
);
break;
case "add":
case 'add':
// add if question is not already in test
$myObjEx = new Exercise();
$myObjEx->read($from_exercise);
$res = "-";
if (!$myObjEx->isInList($in_questionid)) {
$res = "<a href='".api_get_self()."?".api_get_cidreq().$getParams."&recup=$in_questionid&fromExercise=$from_exercise'>";
$res .= Display::return_icon("view_more_stats.gif", get_lang('InsertALinkToThisQuestionInTheExercise'));
$res .= "</a>";
} else {
$res = "-";
}
unset($myObjEx);
break;
case "clone":
case 'clone':
$url = api_get_self()."?".api_get_cidreq().$getParams."&question_copy=$in_questionid&course_id=$in_selected_course&fromExercise=$from_exercise";
$res = Display::url(
Display::return_icon('cd.png', get_lang('ReUseACopyInCurrentTest')),
@ -953,7 +946,7 @@ function get_question_type_for_question($in_selectedcourse, $in_questionid)
$questionType = null;
if (!empty($myObjQuestion)) {
list($typeImg, $typeExpl) = $myObjQuestion->get_type_icon_html();
$questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, array(), 32), array());
$questionType = Display::tag('div', Display::return_icon($typeImg, $typeExpl, [], 32), []);
unset($myObjQuestion);
}
return $questionType;

@ -2781,7 +2781,7 @@ function api_is_coach($session_id = 0, $courseId = null, $check_student_view = t
$session_table = Database::get_main_table(TABLE_MAIN_SESSION);
$session_rel_course_rel_user_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
$sessionIsCoach = null;
$sessionIsCoach = [];
if (!empty($courseId)) {
$sql = "SELECT DISTINCT s.id, name, access_start_date, access_end_date

File diff suppressed because it is too large Load Diff

@ -38,8 +38,13 @@ class ExerciseShowFunctions
$originalStudentAnswer = '',
$showTotalScoreAndUserChoices
) {
$answerHTML = FillBlanks::getHtmlDisplayForAnswer($answer, $feedbackType, $resultsDisabled, $showTotalScoreAndUserChoices);
/*if (strpos($originalStudentAnswer, 'font color') !== false) {
$answerHTML = FillBlanks::getHtmlDisplayForAnswer(
$answer,
$feedbackType,
$resultsDisabled,
$showTotalScoreAndUserChoices
);
/* if (strpos($originalStudentAnswer, 'font color') !== false) {
$answerHTML = $originalStudentAnswer;
}*/
@ -55,13 +60,14 @@ class ExerciseShowFunctions
</td>
<?php
if (!api_is_allowed_to_edit(null, true) && $feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) { ?>
if (!api_is_allowed_to_edit(null, true) && $feedbackType != EXERCISE_FEEDBACK_TYPE_EXAM) {
?>
<td>
<?php
$comm = Event::get_comments($id, $questionId);
?>
$comm = Event::get_comments($id, $questionId); ?>
</td>
<?php } ?>
<?php
} ?>
</tr>
<?php
}
@ -178,8 +184,7 @@ class ExerciseShowFunctions
$fileUrl = null,
$results_disabled = 0,
$questionScore = 0
)
{
) {
if (isset($fileUrl)) {
echo '
<tr>
@ -190,11 +195,11 @@ class ExerciseShowFunctions
if (empty($id)) {
echo '<tr>';
echo Display::tag('td', Security::remove_XSS($answer), array('width'=>'55%'));
echo Display::tag('td', Security::remove_XSS($answer), ['width'=>'55%']);
echo '</tr>';
if (!$questionScore && $feedback_type != EXERCISE_FEEDBACK_TYPE_EXAM) {
echo '<tr>';
echo Display::tag('td', ExerciseLib::getNotCorrectedYetText(), array('width'=>'45%'));
echo Display::tag('td', ExerciseLib::getNotCorrectedYetText(), ['width'=>'45%']);
echo '</tr>';
} else {
echo '<tr><td>&nbsp;</td></tr>';
@ -250,7 +255,7 @@ class ExerciseShowFunctions
}
}
$hotspot_colors = array(
$hotspot_colors = [
"", // $i starts from 1 on next loop (ugly fix)
"#4271B5",
"#FE8E16",
@ -265,9 +270,7 @@ class ExerciseShowFunctions
"#ED2024",
"#3B3B3B",
"#F7BDE2"
);
?>
]; ?>
<table class="data_table">
<tr>
<td class="text-center" width="5%">
@ -354,29 +357,26 @@ class ExerciseShowFunctions
}
}
$icon = in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION)) ? 'radio' : 'checkbox';
$icon = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
$icon .= $studentChoice ? '_on' : '_off';
$icon .= '.png';
$iconAnswer = in_array($answerType, array(UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION)) ? 'radio' : 'checkbox';
$iconAnswer = in_array($answerType, [UNIQUE_ANSWER, UNIQUE_ANSWER_NO_OPTION]) ? 'radio' : 'checkbox';
$iconAnswer .= $answerCorrect ? '_on' : '_off';
$iconAnswer .= '.png';
?>
$iconAnswer .= '.png'; ?>
<tr>
<td width="5%">
<?php echo Display::return_icon($icon, null, null, ICON_SIZE_TINY); ?>
</td>
<td width="5%">
<?php if (!$hide_expected_answer) {
echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY);
} else {
echo "-";
} ?>
echo Display::return_icon($iconAnswer, null, null, ICON_SIZE_TINY);
} else {
echo "-";
} ?>
</td>
<td width="40%">
<?php
echo $answer;
?>
echo $answer; ?>
</td>
<?php

@ -227,28 +227,21 @@
}
var point = getPointOnImage(self.el, e.clientX, e.clientY);
elementModel = new TextModel({x: point.x, y: point.y, text: ''});
self.elementsCollection.add(elementModel);
elementModel = null;
isMoving = false;
})
.on('mousedown', function (e) {
e.preventDefault();
var point = getPointOnImage(self.el, e.clientX, e.clientY);
if (isMoving || "0" !== self.$rdbOptions.filter(':checked').val() || elementModel) {
return;
}
elementModel = new SvgPathModel({points: [[point.x, point.y]]});
self.elementsCollection.add(elementModel);
isMoving = true;
})
.on('mousemove', function (e) {
@ -259,7 +252,6 @@
}
var point = getPointOnImage(self.el, e.clientX, e.clientY);
elementModel.addPoint(point.x, point.y);
})
.on('mouseup', function (e) {
@ -270,7 +262,6 @@
}
elementModel = null;
isMoving = false;
});
};
@ -334,49 +325,43 @@
window.AnnotationQuestion = function (userSettings) {
$(document).on('ready', function () {
var
settings = $.extend(
{
questionId: 0,
exerciseId: 0,
relPath: '/'
},
userSettings
),
xhrUrl = 'exercise/annotation_user.php',
$container = $('#annotation-canvas-' + settings.questionId);
$
.getJSON(settings.relPath + xhrUrl, {
question_id: parseInt(settings.questionId),
exe_id: parseInt(settings.exerciseId)
})
.done(function (questionInfo) {
var image = new Image();
image.onload = function () {
var elementsCollection = new ElementsCollection(),
canvas = new AnnotationCanvasView(elementsCollection, this, settings.questionId);
$container
.html(canvas.render().el);
/** @namespace questionInfo.answers.paths */
$.each(questionInfo.answers.paths, function (i, pathInfo) {
var pathModel = SvgPathModel.decode(pathInfo);
elementsCollection.add(pathModel);
});
/** @namespace questionInfo.answers.texts */
$(questionInfo.answers.texts).each(function (i, textInfo) {
var textModel = TextModel.decode(textInfo);
elementsCollection.add(textModel);
});
};
image.src = questionInfo.image.path;
});
var settings = $.extend(
{
questionId: 0,
exerciseId: 0,
relPath: '/'
},
userSettings
),
xhrUrl = 'exercise/annotation_user.php?' + _p.web_cid_query,
$container = $('#annotation-canvas-' + settings.questionId);
$.getJSON(settings.relPath + xhrUrl, {
question_id: parseInt(settings.questionId),
exe_id: parseInt(settings.exerciseId),
course_id: parseInt(settings.courseId)
})
.done(function (questionInfo) {
var image = new Image();
image.onload = function () {
var elementsCollection = new ElementsCollection(),
canvas = new AnnotationCanvasView(elementsCollection, this, settings.questionId);
$container.html(canvas.render().el);
/** @namespace questionInfo.answers.paths */
$.each(questionInfo.answers.paths, function (i, pathInfo) {
var pathModel = SvgPathModel.decode(pathInfo);
elementsCollection.add(pathModel);
});
/** @namespace questionInfo.answers.texts */
$(questionInfo.answers.texts).each(function (i, textInfo) {
var textModel = TextModel.decode(textInfo);
elementsCollection.add(textModel);
});
};
image.src = questionInfo.image.path;
});
});
};
})(window, window.jQuery);

@ -12,8 +12,12 @@ if (api_get_setting('more_buttons_maximized_mode') === 'true') {
$template = new Template();
$template->setCSSEditor();
$template->assign('moreButtonsInMaximizedMode', $moreButtonsInMaximizedMode);
$template->assign('course_condition', api_get_cidreq());
$courseId = api_get_course_int_id();
$courseCondition = '';
if (!empty($courseId)) {
$courseCondition = api_get_cidreq();
}
$template->assign('course_condition', $courseCondition);
header('Content-type: application/x-javascript');
$template->display($template->get_template('javascript/editor/ckeditor/config_js.tpl'));

@ -101,14 +101,12 @@ window.HotspotQuestion = (function () {
if (x >= startX) {
width = x - startX;
this.set('radiusX', Math.round(width / 2));
this.set('centerX', startX + this.get('radiusX'));
}
if (y >= startY) {
height = y - startY;
this.set('radiusY', Math.round(height / 2));
this.set('centerY', startY + this.get('radiusY'));
}
@ -258,12 +256,9 @@ window.HotspotQuestion = (function () {
var HotspotSVG = function (modelModel, index) {
var self = this;
this.model = modelModel;
this.hotspotIndex = index;
this.el = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
this.model.onChange(function (hotspotModel) {
self.render();
});
@ -368,7 +363,6 @@ window.HotspotQuestion = (function () {
</div>\n\
';
$el.html(template);
$el.find('select')
.on('change', function () {
selectedHotspotIndex = self.hotspotIndex;
@ -747,7 +741,6 @@ window.HotspotQuestion = (function () {
hotspotsSVG = new AdminHotspotsSVG(hotspotsCollection, this);
$(config.selector).css('width', this.width).append(hotspotsSVG.render().el);
$(config.selector).parent().prepend('\n\
<div id="hotspot-messages" class="alert alert-info">\n\
<h4><span class="fa fa-info-circle" aria-hidden="true"></span> ' + lang.HotspotStatus1 + '</h4>\n\
@ -952,14 +945,14 @@ window.HotspotQuestion = (function () {
answersCollection = new AnswersCollection(),
hotspotsSVG = new UserHotspotsSVG(hotspotsCollection, answersCollection, this);
$(config.selector).css('width', this.width + 20).append(hotspotsSVG.render().el);
$(config.selector).css('width', this.width).append(hotspotsSVG.render().el);
$(config.selector).parent().prepend('\n\
<div id="hotspot-messages-' + config.questionId + '" class="alert alert-info hotspot">\n\
<p>\n\
<div id="hotspot-messages-' + config.questionId + '" class="alert alert-info">\n\
<h4>\n\
<span class="fa fa-info-circle" aria-hidden="true"></span>\n\
<span></span>\n\
</p>\n\
</h4>\n\
</div>\n\
');

@ -270,6 +270,25 @@ QFAMS.moveSelection = function (qfamsName, selectLeft, selectRight, selectHidden
// Set the appropriate items as 'selected in the hidden select.
// These are the values that will actually be posted with the form.
QFAMS.updateHidden(selectHidden, selectRight);
// Order alphabetically
//var sourceId = $(source).attr('id');
var targetId = $(target).attr('id');
var options = $('#' + targetId +' option');
var arr = options.map(function(_, o) { return { t: $(o).text(), v: o.value }; }).get();
arr.sort(function (o1, o2) {
//return o1.t > o2.t ? 1 : o1.t < o2.t ? -1 : 0;
// Ignore case
var t1 = o1.t.toLowerCase(), t2 = o2.t.toLowerCase();
return t1 > t2 ? 1 : t1 < t2 ? -1 : 0;
});
options.each(function(i, o) {
o.value = arr[i].v;
$(o).text(arr[i].t);
});
};
/**

Loading…
Cancel
Save