chamilo /
chamilo-lms
| 1 | <?php |
||
| 2 | /* For license terms, see /license.txt */ |
||
| 3 | /** |
||
| 4 | * Functions. |
||
| 5 | * |
||
| 6 | * @package chamilo.plugin.test2pdf |
||
| 7 | */ |
||
| 8 | $letters = [ |
||
| 9 | 'a', |
||
| 10 | 'b', |
||
| 11 | 'c', |
||
| 12 | 'd', |
||
| 13 | 'e', |
||
| 14 | 'f', |
||
| 15 | 'g', |
||
| 16 | 'h', |
||
| 17 | 'i', |
||
| 18 | 'j', |
||
| 19 | 'k', |
||
| 20 | 'l', |
||
| 21 | 'm', |
||
| 22 | 'n', |
||
| 23 | 'o', |
||
| 24 | 'p', |
||
| 25 | 'q', |
||
| 26 | 'r', |
||
| 27 | 's', |
||
| 28 | 't', |
||
| 29 | 'u', |
||
| 30 | 'v', |
||
| 31 | 'w', |
||
| 32 | 'x', |
||
| 33 | 'y', |
||
| 34 | 'z', |
||
| 35 | ]; |
||
| 36 | |||
| 37 | /** |
||
| 38 | * List exercises. |
||
| 39 | * |
||
| 40 | * @param int $courseId Course ID |
||
| 41 | * @param int $sessionId Session ID |
||
| 42 | * |
||
| 43 | * @throws Exception |
||
| 44 | * |
||
| 45 | * @return array Results (list of exercise details) |
||
| 46 | */ |
||
| 47 | function showExerciseCourse($courseId, $sessionId = 0) |
||
| 48 | { |
||
| 49 | $tableQuiz = Database::get_course_table(TABLE_QUIZ_TEST); |
||
| 50 | $tableLpItem = Database::get_course_table(TABLE_LP_ITEM); |
||
| 51 | $courseId = (int) $courseId; |
||
| 52 | $sessionId = (int) $sessionId; |
||
| 53 | $conditionSession = api_get_session_condition($sessionId, true, true, 'a.session_id'); |
||
| 54 | $sql = "SELECT a.* |
||
| 55 | FROM $tableQuiz a |
||
| 56 | LEFT JOIN $tableLpItem b ON a.iid = b.path AND a.c_id = b.c_id |
||
| 57 | WHERE a.c_id = $courseId |
||
| 58 | AND (a.active = 1 OR (item_type = 'quiz' AND b.c_id = $courseId)) |
||
| 59 | $conditionSession |
||
| 60 | ORDER BY a.title ASC;"; |
||
| 61 | $res = Database::query($sql); |
||
| 62 | $aux = []; |
||
| 63 | while ($row = Database::fetch_assoc($res)) { |
||
| 64 | $aux[] = $row; |
||
| 65 | } |
||
| 66 | |||
| 67 | return $aux; |
||
| 68 | } |
||
| 69 | |||
| 70 | /** |
||
| 71 | * List quiz details. |
||
| 72 | * |
||
| 73 | * @throws Exception |
||
| 74 | * |
||
| 75 | * @return array Results (list of quiz details) |
||
| 76 | */ |
||
| 77 | function getInfoQuiz($courseId, $id) |
||
| 78 | { |
||
| 79 | $courseId = (int) $courseId; |
||
| 80 | $id = (int) $id; |
||
| 81 | $tableQuiz = Database::get_course_table(TABLE_QUIZ_TEST); |
||
| 82 | $sql = "SELECT * FROM $tableQuiz WHERE iid = $id"; |
||
| 83 | $res = Database::query($sql); |
||
| 84 | $row = Database::fetch_assoc($res); |
||
| 85 | |||
| 86 | return $row; |
||
| 87 | } |
||
| 88 | |||
| 89 | /** |
||
| 90 | * List question_id. |
||
| 91 | * |
||
| 92 | * @throws Exception |
||
| 93 | * |
||
| 94 | * @return array Results (list question ID) |
||
| 95 | */ |
||
| 96 | function getQuestionsFromCourse($courseId, $quizId, $sessionId = 0) |
||
| 97 | { |
||
| 98 | $courseId = (int) $courseId; |
||
| 99 | $quizId = (int) $quizId; |
||
| 100 | $sessionId = (int) $sessionId; |
||
| 101 | |||
| 102 | $tableQuizQuestion = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION); |
||
| 103 | $tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION); |
||
| 104 | $tableQuiz = Database::get_course_table(TABLE_QUIZ_TEST); |
||
| 105 | $conditionSession = api_get_session_condition($sessionId, true, true, 'q.session_id'); |
||
| 106 | |||
| 107 | $sql = "SELECT a.question_id AS question_id |
||
| 108 | FROM $tableQuizQuestion a |
||
| 109 | INNER JOIN $tableQuestion b ON a.question_id = b.iid |
||
| 110 | INNER JOIN $tableQuiz q ON q.iid = a.exercice_id |
||
| 111 | WHERE a.c_id = $courseId AND a.exercice_id = $quizId |
||
| 112 | AND (b.type IN (1, 2, 3, 9, 10, 11, 12, 14)) |
||
| 113 | $conditionSession |
||
| 114 | ORDER BY question_order ASC;"; |
||
| 115 | $res = Database::query($sql); |
||
| 116 | $aux = []; |
||
| 117 | while ($row = Database::fetch_assoc($res)) { |
||
| 118 | $aux[] = $row['question_id']; |
||
| 119 | } |
||
| 120 | |||
| 121 | return $aux; |
||
| 122 | } |
||
| 123 | |||
| 124 | /** |
||
| 125 | * List question details. |
||
| 126 | * |
||
| 127 | * @throws Exception |
||
| 128 | * |
||
| 129 | * @return array Results (list of question details) |
||
| 130 | */ |
||
| 131 | function getInfoQuestion($courseId, $id) |
||
| 132 | { |
||
| 133 | $courseId = (int) $courseId; |
||
| 134 | $id = (int) $id; |
||
| 135 | $tableQuestion = Database::get_course_table(TABLE_QUIZ_QUESTION); |
||
| 136 | $sql = "SELECT * FROM $tableQuestion |
||
| 137 | WHERE |
||
| 138 | iid = $id |
||
| 139 | AND (type IN (1, 2, 3, 9, 10, 11, 12, 14))"; |
||
| 140 | $res = Database::query($sql); |
||
| 141 | $row = Database::fetch_assoc($res); |
||
| 142 | |||
| 143 | return $row; |
||
| 144 | } |
||
| 145 | |||
| 146 | /** |
||
| 147 | * List answer details. |
||
| 148 | * |
||
| 149 | * @throws Exception |
||
| 150 | * |
||
| 151 | * @return array Results (list of answer by question_id) |
||
| 152 | */ |
||
| 153 | function getAnswers($courseId, $id) |
||
| 154 | { |
||
| 155 | $courseId = (int) $courseId; |
||
| 156 | $id = (int) $id; |
||
| 157 | $tableQuizAnswer = Database::get_course_table(TABLE_QUIZ_ANSWER); |
||
| 158 | $sql = "SELECT * FROM $tableQuizAnswer |
||
| 159 | WHERE question_id = $id |
||
| 160 | ORDER BY position ASC;"; |
||
| 161 | $res = Database::query($sql); |
||
| 162 | $aux = []; |
||
| 163 | while ($row = Database::fetch_assoc($res)) { |
||
| 164 | $aux[] = $row; |
||
| 165 | } |
||
| 166 | |||
| 167 | return $aux; |
||
| 168 | } |
||
| 169 | |||
| 170 | /** |
||
| 171 | * Information of an answer type Fill in the blanks. |
||
| 172 | * |
||
| 173 | * @param $answer |
||
| 174 | * |
||
| 175 | * @return array |
||
| 176 | */ |
||
| 177 | function getAnswerFillInBlanks($answer) |
||
| 178 | { |
||
| 179 | $listAnswerResults = []; |
||
| 180 | $listAnswerResults['text'] = ''; |
||
| 181 | $listAnswerResults['words_count'] = 0; |
||
| 182 | $listAnswerResults['words_with_bracket'] = []; |
||
| 183 | $listAnswerResults['words'] = []; |
||
| 184 | $listAnswerResults['weighting'] = []; |
||
| 185 | $listAnswerResults['input_size'] = []; |
||
| 186 | $listAnswerResults['switchable'] = ''; |
||
| 187 | $listAnswerResults['student_answer'] = []; |
||
| 188 | $listAnswerResults['student_score'] = []; |
||
| 189 | $listAnswerResults['blank_separator_number'] = 0; |
||
| 190 | $listDoubleColon = []; |
||
| 191 | |||
| 192 | api_preg_match("/(.*)::(.*)$/s", $answer, $listResult); |
||
| 193 | |||
| 194 | if (count($listResult) < 2) { |
||
| 195 | $listDoubleColon[] = ''; |
||
| 196 | $listDoubleColon[] = ''; |
||
| 197 | } else { |
||
| 198 | $listDoubleColon[] = $listResult[1]; |
||
| 199 | $listDoubleColon[] = $listResult[2]; |
||
| 200 | } |
||
| 201 | |||
| 202 | $listAnswerResults['system_string'] = $listDoubleColon[1]; |
||
| 203 | |||
| 204 | // Make sure we only take the last bit to find special marks |
||
| 205 | $listArobaseSplit = explode('@', $listDoubleColon[1]); |
||
| 206 | |||
| 207 | if (count($listArobaseSplit) < 2) { |
||
| 208 | $listArobaseSplit[1] = ''; |
||
| 209 | } |
||
| 210 | |||
| 211 | // Take the complete string except after the last '::' |
||
| 212 | $listDetails = explode(':', $listArobaseSplit[0]); |
||
| 213 | |||
| 214 | // < number of item after the ::[score]:[size]:[separator_id]@ , here there are 3 |
||
| 215 | if (count($listDetails) < 3) { |
||
| 216 | $listWeightings = explode(',', $listDetails[0]); |
||
| 217 | $listSizeOfInput = []; |
||
| 218 | for ($i = 0; $i < count($listWeightings); $i++) { |
||
|
0 ignored issues
–
show
|
|||
| 219 | $listSizeOfInput[] = 200; |
||
| 220 | } |
||
| 221 | $blankSeparatorNumber = 0; // 0 is [...] |
||
| 222 | } else { |
||
| 223 | $listWeightings = explode(',', $listDetails[0]); |
||
| 224 | $listSizeOfInput = explode(',', $listDetails[1]); |
||
| 225 | $blankSeparatorNumber = $listDetails[2]; |
||
| 226 | } |
||
| 227 | |||
| 228 | $listSeparators = [ |
||
| 229 | ['[', ']'], |
||
| 230 | ['{', '}'], |
||
| 231 | ['(', ')'], |
||
| 232 | ['*', '*'], |
||
| 233 | ['#', '#'], |
||
| 234 | ['%', '%'], |
||
| 235 | ['$', '$'], |
||
| 236 | ]; |
||
| 237 | |||
| 238 | $listAnswerResults['text'] = $listDoubleColon[0]; |
||
| 239 | $listAnswerResults['weighting'] = $listWeightings; |
||
| 240 | $listAnswerResults['input_size'] = $listSizeOfInput; |
||
| 241 | $listAnswerResults['switchable'] = $listArobaseSplit[1]; |
||
| 242 | $listAnswerResults['blank_separator_start'] = $listSeparators[$blankSeparatorNumber][0]; |
||
| 243 | $listAnswerResults['blank_separator_end'] = $listSeparators[$blankSeparatorNumber][1]; |
||
| 244 | $listAnswerResults['blank_separator_number'] = $blankSeparatorNumber; |
||
| 245 | |||
| 246 | $blankCharStart = $listSeparators[$blankSeparatorNumber][0]; |
||
| 247 | $blankCharEnd = $listSeparators[$blankSeparatorNumber][1]; |
||
| 248 | $blankCharStartForRegexp = escapeForRegexp($blankCharStart); |
||
| 249 | $blankCharEndForRegexp = escapeForRegexp($blankCharEnd); |
||
| 250 | |||
| 251 | // Get all blanks words |
||
| 252 | $listAnswerResults['words_count'] = api_preg_match_all( |
||
| 253 | '/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/', |
||
| 254 | $listDoubleColon[0], |
||
| 255 | $listWords |
||
| 256 | ); |
||
| 257 | |||
| 258 | if ($listAnswerResults['words_count'] > 0) { |
||
| 259 | $listAnswerResults['words_with_bracket'] = $listWords[0]; |
||
| 260 | // remove [ and ] in string |
||
| 261 | array_walk( |
||
| 262 | $listWords[0], |
||
| 263 | function (&$value, $key, $tabBlankChar) { |
||
| 264 | $trimChars = ''; |
||
| 265 | for ($i = 0; $i < count($tabBlankChar); $i++) { |
||
|
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
|
|||
| 266 | $trimChars .= $tabBlankChar[$i]; |
||
| 267 | } |
||
| 268 | $value = trim($value, $trimChars); |
||
| 269 | $key = trim($key); |
||
| 270 | }, |
||
| 271 | [$blankCharStart, $blankCharEnd] |
||
| 272 | ); |
||
| 273 | $listAnswerResults['words'] = $listWords[0]; |
||
| 274 | } |
||
| 275 | |||
| 276 | // Get all common words |
||
| 277 | $commonWords = api_preg_replace( |
||
| 278 | '/'.$blankCharStartForRegexp.'[^'.$blankCharEndForRegexp.']*'.$blankCharEndForRegexp.'/', |
||
| 279 | '::', |
||
| 280 | $listDoubleColon[0] |
||
| 281 | ); |
||
| 282 | $listAnswerResults['common_words'] = explode('::', $commonWords); |
||
| 283 | |||
| 284 | return $listAnswerResults; |
||
| 285 | } |
||
| 286 | |||
| 287 | /** |
||
| 288 | * Escapes text used for question type Fill in the blanks. |
||
| 289 | * |
||
| 290 | * @param $inChar |
||
| 291 | * |
||
| 292 | * @return mixed|string |
||
| 293 | */ |
||
| 294 | function escapeForRegexp($inChar) |
||
| 295 | { |
||
| 296 | $listChars = [ |
||
| 297 | ".", |
||
| 298 | "+", |
||
| 299 | "*", |
||
| 300 | "?", |
||
| 301 | "[", |
||
| 302 | "^", |
||
| 303 | "]", |
||
| 304 | "$", |
||
| 305 | "(", |
||
| 306 | ")", |
||
| 307 | "{", |
||
| 308 | "}", |
||
| 309 | "=", |
||
| 310 | "!", |
||
| 311 | ">", |
||
| 312 | "|", |
||
| 313 | ":", |
||
| 314 | "-", |
||
| 315 | ")", |
||
| 316 | ]; |
||
| 317 | |||
| 318 | if (in_array($inChar, $listChars)) { |
||
| 319 | return "\\".$inChar; |
||
| 320 | } else { |
||
| 321 | return $inChar; |
||
| 322 | } |
||
| 323 | } |
||
| 324 | |||
| 325 | /** |
||
| 326 | * Clear the answer entered. |
||
| 327 | * |
||
| 328 | * @param string $answer |
||
| 329 | * |
||
| 330 | * @return string |
||
| 331 | */ |
||
| 332 | function clearStudentAnswer($answer) |
||
| 333 | { |
||
| 334 | $answer = api_html_entity_decode($answer); |
||
| 335 | $answer = api_preg_replace('/\s\s+/', ' ', $answer); // replace excess white spaces |
||
| 336 | $answer = str_replace(''', ''', $answer); |
||
| 337 | $answer = strtr($answer, array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES))); |
||
| 338 | |||
| 339 | return trim($answer); |
||
| 340 | } |
||
| 341 | |||
| 342 | /** |
||
| 343 | * Remove all html tag. |
||
| 344 | * |
||
| 345 | * @param string $string The string to be stripped of HTML |
||
| 346 | * |
||
| 347 | * @return string clean of html tag |
||
| 348 | */ |
||
| 349 | function removeHtml($string) |
||
| 350 | { |
||
| 351 | $txt = str_replace("<html>", "", $string); |
||
| 352 | $txt = str_replace("<head>", "", $txt); |
||
| 353 | $txt = str_replace("<title>", "", $txt); |
||
| 354 | $txt = str_replace("</title>", "", $txt); |
||
| 355 | $txt = str_replace("</head>", "", $txt); |
||
| 356 | $txt = str_replace("<body>", "", $txt); |
||
| 357 | $txt = str_replace("</body>", "", $txt); |
||
| 358 | $txt = str_replace("</html>", "", $txt); |
||
| 359 | $txt = strip_tags($txt); |
||
| 360 | $txt = str_replace(chr(13).chr(10), "", $txt); |
||
| 361 | $txt = str_replace(" ", " ", $txt); |
||
| 362 | $txt = str_replace("Á", "Á", $txt); |
||
| 363 | $txt = str_replace("á", "á", $txt); |
||
| 364 | $txt = str_replace("É", "É", $txt); |
||
| 365 | $txt = str_replace("é", "é", $txt); |
||
| 366 | $txt = str_replace("Í", "Í", $txt); |
||
| 367 | $txt = str_replace("í", "í", $txt); |
||
| 368 | $txt = str_replace("Ó", "Ó", $txt); |
||
| 369 | $txt = str_replace("ó", "ó", $txt); |
||
| 370 | $txt = str_replace("Ú", "Ú", $txt); |
||
| 371 | $txt = str_replace("ú", "ú", $txt); |
||
| 372 | $txt = str_replace("Ñ", "Ñ", $txt); |
||
| 373 | $txt = str_replace("ñ", "ñ", $txt); |
||
| 374 | $txt = str_replace("à", "à", $txt); |
||
| 375 | $txt = str_replace("À", "À", $txt); |
||
| 376 | $txt = str_replace("¡", "¡", $txt); |
||
| 377 | $txt = str_replace("·", "·", $txt); |
||
| 378 | $txt = str_replace("Ç", "Ç", $txt); |
||
| 379 | $txt = str_replace("ç", "ç", $txt); |
||
| 380 | $txt = str_replace(""", '"', $txt); |
||
| 381 | $txt = str_replace("ª", 'ª', $txt); |
||
| 382 | $txt = str_replace("º", 'º', $txt); |
||
| 383 | $txt = str_replace("&", '&', $txt); |
||
| 384 | $txt = str_replace("•", '•', $txt); |
||
| 385 | $txt = str_replace("¿", '¿', $txt); |
||
| 386 | $txt = str_replace("€", 'EUR', $txt); |
||
| 387 | $txt = str_replace("ü", 'ü', $txt); |
||
| 388 | $txt = str_replace("Ü", 'Ü', $txt); |
||
| 389 | $txt = str_replace("¨", '¨', $txt); |
||
| 390 | |||
| 391 | return $txt; |
||
| 392 | } |
||
| 393 | |||
| 394 | /** |
||
| 395 | * Remove all html tag. |
||
| 396 | * |
||
| 397 | * @param string $string The string to be stripped of accents |
||
| 398 | * |
||
| 399 | * @return string clean of html tag |
||
| 400 | */ |
||
| 401 | function removeQuotes($string) |
||
| 402 | { |
||
| 403 | $txt = str_replace(" ", " ", $string); |
||
| 404 | $txt = str_replace("Á", "Á", $txt); |
||
| 405 | $txt = str_replace("á", "á", $txt); |
||
| 406 | $txt = str_replace("É", "É", $txt); |
||
| 407 | $txt = str_replace("é", "é", $txt); |
||
| 408 | $txt = str_replace("Í", "Í", $txt); |
||
| 409 | $txt = str_replace("í", "í", $txt); |
||
| 410 | $txt = str_replace("Ó", "Ó", $txt); |
||
| 411 | $txt = str_replace("ó", "ó", $txt); |
||
| 412 | $txt = str_replace("Ú", "Ú", $txt); |
||
| 413 | $txt = str_replace("ú", "ú", $txt); |
||
| 414 | $txt = str_replace("Ñ", "Ñ", $txt); |
||
| 415 | $txt = str_replace("ñ", "ñ", $txt); |
||
| 416 | $txt = str_replace(""", '"', $txt); |
||
| 417 | $txt = str_replace("ª", 'ª', $txt); |
||
| 418 | $txt = str_replace("º", 'º', $txt); |
||
| 419 | $txt = str_replace("&", '&', $txt); |
||
| 420 | $txt = str_replace("•", '•', $txt); |
||
| 421 | $txt = str_replace("¿ &", '¿', $txt); |
||
| 422 | $txt = str_replace("à", "à", $txt); |
||
| 423 | $txt = str_replace("À", "À", $txt); |
||
| 424 | $txt = str_replace("¡", "¡", $txt); |
||
| 425 | $txt = str_replace("·", "·", $txt); |
||
| 426 | $txt = str_replace("Ç", "Ç", $txt); |
||
| 427 | $txt = str_replace("ç", "ç", $txt); |
||
| 428 | $txt = str_replace("€", 'EUR', $txt); |
||
| 429 | $txt = str_replace("ü", 'ü', $txt); |
||
| 430 | $txt = str_replace("Ü", 'Ü', $txt); |
||
| 431 | $txt = str_replace("uml;", '¨', $txt); |
||
| 432 | |||
| 433 | return $txt; |
||
| 434 | } |
||
| 435 |
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: