Skip to content

Commit

Permalink
Admin: Add config allow_mandatory_question_in_category BT#17789
Browse files Browse the repository at this point in the history
Allow mandatory selectable questions when using setting
"Question selection type" =
"Ordered categories alphabetically with random questions'
  • Loading branch information
jmontoyaa committed Oct 30, 2020
1 parent ed53f75 commit 9ff5505
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 55 deletions.
4 changes: 1 addition & 3 deletions main/exercise/ReadingComprehension.php
Expand Up @@ -179,15 +179,13 @@ public function createForm(&$form, $exercise)
*/
public static function get_default_levels()
{
$select_level = [
return [
1 => sprintf(get_lang('ReadingComprehensionLevelX'), self::$speeds[1]),
2 => sprintf(get_lang('ReadingComprehensionLevelX'), self::$speeds[2]),
3 => sprintf(get_lang('ReadingComprehensionLevelX'), self::$speeds[3]),
4 => sprintf(get_lang('ReadingComprehensionLevelX'), self::$speeds[4]),
5 => sprintf(get_lang('ReadingComprehensionLevelX'), self::$speeds[5]),
];

return $select_level;
}

/**
Expand Down
78 changes: 59 additions & 19 deletions main/exercise/TestCategory.php
@@ -1,4 +1,5 @@
<?php

/* For licensing terms, see /license.txt */

use ChamiloSession as Session;
Expand Down Expand Up @@ -158,7 +159,7 @@ public function removeCategory($id)
public function modifyCategory($courseId = 0)
{
$table = Database::get_course_table(TABLE_QUIZ_QUESTION_CATEGORY);
$id = intval($this->id);
$id = (int) $this->id;
$name = Database::escape_string($this->name);
$description = Database::escape_string($this->description);
$cat = $this->getCategory($id, $courseId);
Expand All @@ -175,7 +176,6 @@ public function modifyCategory($courseId = 0)
WHERE id = $id AND c_id = ".$courseId;
Database::query($sql);

// item_property update
api_item_property_update(
$courseInfo,
TOOL_TEST_CATEGORY,
Expand Down Expand Up @@ -257,6 +257,17 @@ public static function getCategoryListInfo($field = '', $courseId = 0)
* @return int
*/
public static function getCategoryForQuestion($questionId, $courseId = 0)
{
$categoryInfo = self::getCategoryInfoForQuestion($questionId, $courseId);

if (!empty($categoryInfo) && isset($categoryInfo['category_id'])) {
return (int) $categoryInfo['category_id'];
}

return 0;
}

public static function getCategoryInfoForQuestion($questionId, $courseId = 0)
{
$courseId = (int) $courseId;
$questionId = (int) $questionId;
Expand All @@ -270,17 +281,15 @@ public static function getCategoryForQuestion($questionId, $courseId = 0)
}

$table = Database::get_course_table(TABLE_QUIZ_QUESTION_REL_CATEGORY);
$sql = "SELECT category_id
$sql = "SELECT *
FROM $table
WHERE question_id = $questionId AND c_id = $courseId";
$res = Database::query($sql);
$result = 0;
if (Database::num_rows($res) > 0) {
$data = Database::fetch_array($res);
$result = (int) $data['category_id'];
return Database::fetch_array($res, 'ASSOC');
}

return $result;
return [];
}

/**
Expand Down Expand Up @@ -314,9 +323,7 @@ public static function getCategoryNameForQuestion($questionId, $courseId = 0)
}

/**
* Return the list of differents categories ID for a test in the current course
* input : test_id
* return : array of category id (integer)
* Return the list of different categories ID for a test in the current course
* hubert.borderiou 07-04-2011.
*
* @param int $exerciseId
Expand Down Expand Up @@ -514,7 +521,8 @@ public static function getCategoriesIdAndName($courseId = 0)
public static function getQuestionsByCat(
$exerciseId,
$check_in_question_list = [],
$categoriesAddedInExercise = []
$categoriesAddedInExercise = [],
$onlyMandatory = false
) {
$tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION);
$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
Expand All @@ -523,6 +531,11 @@ public static function getQuestionsByCat(
$exerciseId = (int) $exerciseId;
$courseId = api_get_course_int_id();

$mandatoryCondition = '';
if ($onlyMandatory) {
$mandatoryCondition = ' AND qrc.mandatory = 1';
}

$sql = "SELECT DISTINCT qrc.question_id, qrc.category_id
FROM $TBL_QUESTION_REL_CATEGORY qrc
INNER JOIN $TBL_EXERCICE_QUESTION eq
Expand All @@ -534,6 +547,7 @@ public static function getQuestionsByCat(
WHERE
exercice_id = $exerciseId AND
qrc.c_id = $courseId
$mandatoryCondition
";

$res = Database::query($sql);
Expand Down Expand Up @@ -589,27 +603,53 @@ public static function getQuestionsByCat(
}

/**
* Returns an array of $numberElements from $array.
* Returns an array of $numberElements from $elements.
*
* @param array $array
* @param array $elements
* @param int $numberElements
* @param bool $shuffle
* @param array $mandatoryElements
*
* @return array
*/
public static function getNElementsFromArray($array, $numberElements, $shuffle = true)
public static function getNElementsFromArray($elements, $numberElements, $shuffle = true, $mandatoryElements = [])
{
$list = $array;
$countElements = count($elements);
$countMandatory = count($mandatoryElements);

if (!empty($countMandatory)) {
if ($countMandatory >= $numberElements) {
if ($shuffle) {
shuffle($mandatoryElements);
}
$elements = array_slice($mandatoryElements, 0, $numberElements);

return $elements;
}

$diffCount = $numberElements - $countMandatory;
$diffElements = array_diff($elements, $mandatoryElements);
if ($shuffle) {
shuffle($diffElements);
}
$elements = array_slice($diffElements, 0, $diffCount);
$totalElements = array_merge($mandatoryElements, $elements);
if ($shuffle) {
shuffle($totalElements);
}

return $totalElements;
}

if ($shuffle) {
shuffle($list);
shuffle($elements);
}

if ($numberElements < count($list)) {
$list = array_slice($list, 0, $numberElements);
if ($numberElements < $countElements) {
$elements = array_slice($elements, 0, $numberElements);
}

return $list;
return $elements;
}

/**
Expand Down
10 changes: 5 additions & 5 deletions main/exercise/admin.php
Expand Up @@ -138,7 +138,7 @@
}

// Exercise object creation.
if (!is_object($objExercise)) {
if (!($objExercise instanceof Exercise)) {
// creation of a new exercise if wrong or not specified exercise ID
if ($exerciseId) {
$objExercise = new Exercise();
Expand All @@ -148,12 +148,12 @@
$showPagination = true;
}
$objExercise->read($exerciseId, $parseQuestionList);
Session::write('objExercise', $objExercise);
}
// saves the object into the session
Session::write('objExercise', $objExercise);
}

if (empty($objExercise)) {
Session::erase('objExercise');
header('Location: '.api_get_path(WEB_CODE_PATH).'exercise/exercise.php?'.api_get_cidreq());
exit;
}
Expand Down Expand Up @@ -336,7 +336,8 @@
api_get_path(WEB_CODE_PATH).'exercise/exercise_report.php?'.api_get_cidreq().'&exerciseId='.$objExercise->id
);

echo '<a href="'.api_get_path(WEB_CODE_PATH).'exercise/exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.
echo '<a
href="'.api_get_path(WEB_CODE_PATH).'exercise/exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$objExercise->id.'">'.
Display::return_icon('settings.png', get_lang('ModifyExercise'), '', ICON_SIZE_MEDIUM).'</a>';

$maxScoreAllQuestions = 0;
Expand Down Expand Up @@ -446,7 +447,6 @@
echo Display::return_message(get_lang('TestFeedbackNotShown'), 'normal');
}

Session::write('objExercise', $objExercise);
Session::write('objQuestion', $objQuestion);
Session::write('objAnswer', $objAnswer);
Display::display_footer();
38 changes: 27 additions & 11 deletions main/exercise/exercise.class.php
Expand Up @@ -205,7 +205,7 @@ public function read($id, $parseQuestionList = true)
$this->is_gradebook_locked = api_resource_is_locked_by_gradebook($id, LINK_EXERCISE);
$this->review_answers = (isset($object->review_answers) && $object->review_answers == 1) ? true : false;
$this->globalCategoryId = isset($object->global_category_id) ? $object->global_category_id : null;
$this->questionSelectionType = isset($object->question_selection_type) ? $object->question_selection_type : null;
$this->questionSelectionType = isset($object->question_selection_type) ? (int) $object->question_selection_type : null;
$this->hideQuestionTitle = isset($object->hide_question_title) ? (int) $object->hide_question_title : 0;
$this->autolaunch = isset($object->autolaunch) ? (int) $object->autolaunch : 0;
$this->exerciseCategoryId = isset($object->exercise_category_id) ? (int) $object->exercise_category_id : null;
Expand Down Expand Up @@ -818,7 +818,6 @@ public function getQuestionListWithCategoryListFilteredByCategorySettings(

// Order/random categories
$cat = new TestCategory();

// Setting category order.
switch ($questionSelectionType) {
case EX_Q_SELECTION_ORDERED: // 1
Expand Down Expand Up @@ -883,12 +882,26 @@ public function getQuestionListWithCategoryListFilteredByCategorySettings(
$question_list,
$categoriesAddedInExercise
);

$questionsByCategoryMandatory = [];
if (EX_Q_SELECTION_CATEGORIES_ORDERED_QUESTIONS_RANDOM == $this->getQuestionSelectionType() &&
api_get_configuration_value('allow_mandatory_question_in_category')
) {
$questionsByCategoryMandatory = TestCategory::getQuestionsByCat(
$this->id,
$question_list,
$categoriesAddedInExercise,
true
);
}

$question_list = $this->pickQuestionsPerCategory(
$categoriesAddedInExercise,
$question_list,
$questions_by_category,
true,
true
true,
$questionsByCategoryMandatory
);
break;
case EX_Q_SELECTION_CATEGORIES_RANDOM_QUESTIONS_RANDOM: // 6
Expand Down Expand Up @@ -6734,10 +6747,7 @@ public function setQuestionList($adminView = false)
// Getting question list.
$questionList = $this->selectQuestionList(true, $adminView);
$this->setMediaList($questionList);
$this->questionList = $this->transformQuestionListWithMedias(
$questionList,
false
);
$this->questionList = $this->transformQuestionListWithMedias($questionList, false);
$this->questionListUncompressed = $this->transformQuestionListWithMedias(
$questionList,
true
Expand Down Expand Up @@ -10239,6 +10249,7 @@ private function getQuestionOrderedList($adminView = false)
* @param array $questions_by_category per category
* @param bool $flatResult
* @param bool $randomizeQuestions
* @param array $questionsByCategoryMandatory
*
* @return array
*/
Expand All @@ -10247,7 +10258,8 @@ private function pickQuestionsPerCategory(
$question_list,
&$questions_by_category,
$flatResult = true,
$randomizeQuestions = false
$randomizeQuestions = false,
$questionsByCategoryMandatory = []
) {
$addAll = true;
$categoryCountArray = [];
Expand Down Expand Up @@ -10283,14 +10295,18 @@ private function pickQuestionsPerCategory(
if ($addAll) {
$numberOfQuestions = 999;
}

if (!empty($numberOfQuestions)) {
$mandatoryQuestions = [];
if (isset($questionsByCategoryMandatory[$category_id])) {
$mandatoryQuestions = $questionsByCategoryMandatory[$category_id];
}

$elements = TestCategory::getNElementsFromArray(
$categoryQuestionList,
$numberOfQuestions,
$randomizeQuestions
$randomizeQuestions,
$mandatoryQuestions
);

if (!empty($elements)) {
$temp_question_list[$category_id] = $elements;
$categoryQuestionList = $elements;
Expand Down

0 comments on commit 9ff5505

Please sign in to comment.