Thank you for downloading quiz.php
Your download should start in 3 seconds... If not please use the download link below
| 1 |
|
|---|---|
| 2 | <?php
|
| 3 | /**
|
| 4 | * JQuarks Component Quiz Model |
| 5 | * |
| 6 | * @version $Id: quiz.php 56 2010-02-09 13:41:53Z mtougorti $ |
| 7 | * @author IP-Tech Labs <labs@iptech-offshore.com> |
| 8 | * @copyright 2009-2010 IP-Tech |
| 9 | * @package JQuarks-Front-Office |
| 10 | * @subpackage Models |
| 11 | * @link http://www.iptechinside.com/labs/projects/show/jquarks |
| 12 | * @since 0.1 |
| 13 | * @license GNU/GPL2 |
| 14 | * |
| 15 | * This program is free software; you can redistribute it and/or |
| 16 | * modify it under the terms of the GNU General Public License |
| 17 | * as published by the Free Software Foundation; version 2 |
| 18 | * of the License. |
| 19 | * |
| 20 | * This program is distributed in the hope that it will be useful, |
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 23 | * GNU General Public License for more details. |
| 24 | * |
| 25 | * You should have received a copy of the GNU General Public License |
| 26 | * along with this program; if not, write to the Free Software |
| 27 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 28 | * or see <http://www.gnu.org/licenses/> |
| 29 | */ |
| 30 | |
| 31 | defined('_JEXEC') or die(); |
| 32 | |
| 33 | jimport('joomla.application.component.model');
|
| 34 | |
| 35 | |
| 36 | class JQuarksModelQuiz extends JModel |
| 37 | {
|
| 38 | var $_questions = null ; |
| 39 | var $_propositions = null ; |
| 40 | var $_sessionId = null ; |
| 41 | |
| 42 | function __construct()
|
| 43 | {
|
| 44 | parent::__construct(); |
| 45 | |
| 46 | $this->_id = (int) JRequest::getVar('id') ; |
| 47 | |
| 48 | // getting the current user
|
| 49 | $this->_user =& JFactory::getUser();
|
| 50 | |
| 51 | if ($this->_user->guest) { |
| 52 | $this->_userId = -1 ; |
| 53 | } else {
|
| 54 | $this->_userId = $this->_user->id ; |
| 55 | } |
| 56 | |
| 57 | $this->quizSessionTable =& JTable::getInstance('quizsession', 'Table') ; |
| 58 | $this->sessionWhoTable =& JTable::getInstance('sessionwho', 'Table') ; |
| 59 | $this->quizAnswerTable =& JTable::getInstance('quizzes_answersessions', 'Table') ; |
| 60 | $this->users_quizzesTable =& JTable::getInstance('users_quizzes', 'Table') ; |
| 61 | } |
| 62 | |
| 63 | |
| 64 | /**
|
| 65 | * sets the id of the quiz |
| 66 | * |
| 67 | */ |
| 68 | function setId($id = 0) |
| 69 | {
|
| 70 | $this->_id = $id;
|
| 71 | } |
| 72 | |
| 73 | |
| 74 | |
| 75 | /**
|
| 76 | * Get the affectation id of the current user to the quiz |
| 77 | * |
| 78 | * @param $quizId |
| 79 | * @return int |
| 80 | */ |
| 81 | function getAffectedId($quizId)
|
| 82 | {
|
| 83 | $config =& JFactory::getConfig(); |
| 84 | $jnow =& JFactory::getDate(); |
| 85 | $jnow->setOffset( $config->getValue('config.offset' ));
|
| 86 | $now = $jnow->toMySQL(true);
|
| 87 | |
| 88 | $query = 'SELECT users_quizzes.id' .
|
| 89 | ' FROM #__jquarks_users_quizzes AS users_quizzes' .
|
| 90 | ' JOIN #__jquarks_quizzes as qui ON qui.id = users_quizzes.quiz_id ' .
|
| 91 | ' WHERE users_quizzes.user_id = ' . $this->_userId . |
| 92 | ' AND users_quizzes.quiz_id = ' . (int)$quizId .
|
| 93 | ' AND users_quizzes.archived <> 1' .
|
| 94 | ' AND qui.published = 1' .
|
| 95 | ' AND qui.publish_up < "' . $now . '"' . |
| 96 | ' AND ( qui.publish_down = "0000-00-00 00:00:00" OR qui.publish_down > "' . $now . '" )' ; |
| 97 | |
| 98 | $this->_db->setQuery($query) ;
|
| 99 | $affectedId = $this->_db->loadResult() ;
|
| 100 | |
| 101 | if($this->_db->getErrorNum()) { |
| 102 | return false ; |
| 103 | } |
| 104 | |
| 105 | return $affectedId ;
|
| 106 | } |
| 107 | |
| 108 | /**
|
| 109 | * True if the quiz of the session argumenthas the property show_results set to 1, |
| 110 | * else return false |
| 111 | * |
| 112 | * @param int $session_id |
| 113 | * @return boolean |
| 114 | * |
| 115 | */ |
| 116 | function isShowResults($session_id)
|
| 117 | {
|
| 118 | $query = 'SELECT quizzes.show_results'.
|
| 119 | ' FROM #__jquarks_quizsession AS session, #__jquarks_users_quizzes AS users, #__jquarks_quizzes AS quizzes' .
|
| 120 | ' WHERE session.id = ' . (int)$session_id .
|
| 121 | ' AND session.affected_id = users.id AND users.quiz_id = quizzes.id';
|
| 122 | $this->_db->setQuery($query) ;
|
| 123 | return $this->_db->loadResult() ; |
| 124 | |
| 125 | |
| 126 | } |
| 127 | |
| 128 | |
| 129 | /**
|
| 130 | * Get the selected Quiz |
| 131 | * |
| 132 | * @param $quizId |
| 133 | * @return array |
| 134 | */ |
| 135 | function &getQuiz($quizId = null) |
| 136 | {
|
| 137 | if ($quizId) {
|
| 138 | $this->_id = (int)$quizId ;
|
| 139 | } |
| 140 | |
| 141 | $config =& JFactory::getConfig(); |
| 142 | $jnow =& JFactory::getDate(); |
| 143 | $jnow->setOffset( $config->getValue('config.offset' ));
|
| 144 | $now = $jnow->toMySQL(true);
|
| 145 | |
| 146 | $query = 'SELECT *' .
|
| 147 | ' FROM #__jquarks_quizzes AS qui' .
|
| 148 | ' WHERE qui.id = ' . $this->_id . |
| 149 | ' AND qui.published = 1' .
|
| 150 | ' AND qui.publish_up < "' . $now . '"' . |
| 151 | ' AND qui.publish_down = "0000-00-00 00:00:00"' .
|
| 152 | ' OR qui.publish_down > "' . $now . '"' ; |
| 153 | |
| 154 | $this->_db->setQuery($query) ;
|
| 155 | $this->_quiz = $this->_db->loadObject(); |
| 156 | if($this->_db->getErrorNum()) { |
| 157 | return false ; |
| 158 | } |
| 159 | |
| 160 | // creating the key
|
| 161 | $paginate = array('use_pagination', 'use_slide', 'question_page') ; |
| 162 | |
| 163 | // making paginate an associative array containg the key created and the explode value it contained
|
| 164 | $toCombine = explode(' ', $this->_quiz->paginate) ; |
| 165 | $this->_quiz->paginate = array_combine($paginate, $toCombine) ;
|
| 166 | |
| 167 | // slicing the attribute we only keep the value
|
| 168 | foreach ($this->_quiz->paginate as &$attrib) |
| 169 | {
|
| 170 | list($att, $value) = explode('=', $attrib) ; |
| 171 | $attrib = $value ; |
| 172 | } |
| 173 | unset($attrib) ;
|
| 174 | |
| 175 | return $this->_quiz ; |
| 176 | } |
| 177 | |
| 178 | /**
|
| 179 | * Get the pagination configuration |
| 180 | * |
| 181 | * @return array |
| 182 | */ |
| 183 | function getParams()
|
| 184 | {
|
| 185 | $params =& JComponentHelper::getParams('com_jquarks');
|
| 186 | |
| 187 | $this->_params['paginate'] = $params->get('usePagination') ; |
| 188 | $this->_params['slide'] = $params->get('useSlide') ; |
| 189 | $this->_params['question_page'] = $params->get('questionPage') ; |
| 190 | |
| 191 | return $this->_params ; |
| 192 | } |
| 193 | |
| 194 | /**
|
| 195 | * Get the questions from the custom sets of questions |
| 196 | * |
| 197 | * @return array |
| 198 | */ |
| 199 | private function getCustomQuestions() |
| 200 | {
|
| 201 | $query = 'SELECT distinct(q.statement), q.id, q.type_id' .
|
| 202 | ' FROM #__jquarks_questions AS q' .
|
| 203 | ' LEFT JOIN #__jquarks_setsofquestions_questions AS soqHaveQ ON soqHaveQ.question_id = q.id' .
|
| 204 | ' WHERE soqHaveQ.setofquestions_id IN' .
|
| 205 | ' (SELECT quiHaveSoq.setofquestions_id
|
| 206 | FROM #__jquarks_quizzes_setsofquestions AS quiHaveSoq |
| 207 | WHERE quiHaveSoq.quiz_id = ' . $this->_id . ')' . |
| 208 | ' ORDER BY soqHaveQ.id' ;
|
| 209 | |
| 210 | $questions = $this->_getList($query);
|
| 211 | if($this->_db->getErrorNum()) { |
| 212 | return false ; |
| 213 | } |
| 214 | |
| 215 | return $questions ;
|
| 216 | } |
| 217 | |
| 218 | /**
|
| 219 | * Get the questions from the random sets of questions |
| 220 | * |
| 221 | * @return array |
| 222 | */ |
| 223 | private function getRandomSets() |
| 224 | {
|
| 225 | $query = 'SELECT randomSet.*' . /*, /*(SELECT count(*) |
| 226 | FROM #__jquarks_questions AS q |
| 227 | WHERE q.category_id = randomSet.category_id |
| 228 | AND q.archived = 0 |
| 229 | ) AS totalQuestions' .*/ |
| 230 | ' FROM #__jquarks_setsofquestions AS soq' .
|
| 231 | ' JOIN #__jquarks_randomsets AS randomSet ON randomSet.set_id = soq.id' .
|
| 232 | ' LEFT JOIN #__jquarks_quizzes_setsofquestions AS quiHaveSoq ON quiHaveSoq.setofquestions_id = soq.id' .
|
| 233 | ' WHERE quiHaveSoq.quiz_id = ' . $this->_id . |
| 234 | //' AND randomSet.category_id <> 0' .
|
| 235 | ' AND randomSet.nquestions <> 0' ;
|
| 236 | |
| 237 | $questions = $this->_getList($query) ;
|
| 238 | if($this->_db->getErrorNum()) { |
| 239 | return false ; |
| 240 | } |
| 241 | |
| 242 | return $questions ;
|
| 243 | } |
| 244 | |
| 245 | /**
|
| 246 | * Get the questions assigned to the current session |
| 247 | * |
| 248 | * @return array |
| 249 | */ |
| 250 | private function getSessionQuestions() |
| 251 | {
|
| 252 | $query = 'SELECT questions_id' .
|
| 253 | ' FROM #__jquarks_quizsession' .
|
| 254 | ' WHERE id = ' . $this->_sessionId ; |
| 255 | |
| 256 | $this->_db->setQuery($query) ;
|
| 257 | $questions = $this->_db->loadResult() ;
|
| 258 | if($this->_db->getErrorNum()) { |
| 259 | return false ; |
| 260 | } |
| 261 | |
| 262 | return $questions ;
|
| 263 | } |
| 264 | |
| 265 | |
| 266 | /**
|
| 267 | * Get all the questions of a specific category that are affected to a given quiz |
| 268 | * |
| 269 | * @todo this method is duplicated in model quiz on back-office remove this one and include the other model |
| 270 | * @param $categoryId |
| 271 | * @param $quizId |
| 272 | * @return array associative |
| 273 | */ |
| 274 | function getQuestionsOfCategoryAffectedToQuiz($quizId, $categoryId = NULL)
|
| 275 | {
|
| 276 | $query = 'SELECT questions.*' .
|
| 277 | ' FROM #__jquarks_quizzes_setsofquestions AS quiHaveSoq' .
|
| 278 | ' JOIN #__jquarks_setsofquestions AS setsOfQuestions ON setsOfQuestions.id = quiHaveSoq.setofquestions_id' .
|
| 279 | ' JOIN #__jquarks_setsofquestions_questions AS soqHaveQ ON soqHaveQ.setofquestions_id = setsOfQuestions.id' .
|
| 280 | ' JOIN #__jquarks_questions AS questions ON questions.id = soqHaveQ.question_id' .
|
| 281 | ' WHERE quiHaveSoq.quiz_id = ' . (int)$quizId ;
|
| 282 | |
| 283 | if ($categoryId) {
|
| 284 | $query .= ' AND questions.category_id = ' . $categoryId ;
|
| 285 | } else {
|
| 286 | $query .= ' AND questions.category_id IS NULL' ;
|
| 287 | } |
| 288 | |
| 289 | $this->_db->setQuery($query) ;
|
| 290 | return $this->_db->loadAssocList() ; |
| 291 | } |
| 292 | |
| 293 | /**
|
| 294 | * Return all the questions of the quiz and initiate the storing of the session |
| 295 | * |
| 296 | * @return array |
| 297 | */ |
| 298 | function getQuestions()
|
| 299 | {
|
| 300 | $questions = $this->getCustomQuestions() ;
|
| 301 | $randomSets = $this->getRandomSets($questions) ;
|
| 302 | |
| 303 | $customQuestions = null;
|
| 304 | |
| 305 | // building the list of the custom questions
|
| 306 | if ($questions)
|
| 307 | {
|
| 308 | foreach ($questions as $question) { |
| 309 | $custom[] = $question->id ; |
| 310 | } |
| 311 | $customQuestions = implode(",", $custom);
|
| 312 | } |
| 313 | |
| 314 | if ($randomSets)
|
| 315 | {
|
| 316 | foreach ($randomSets as $randomSet) |
| 317 | {
|
| 318 | $neededNumber = $randomSet->nquestions ; |
| 319 | |
| 320 | if ($randomSet->category_id) {
|
| 321 | $totalNumber = $this->getQuestionsOfCategoryAffectedToQuiz($this->_quiz->id, $randomSet->category_id) ; |
| 322 | } else {
|
| 323 | $totalNumber = $this->getQuestionsOfCategoryAffectedToQuiz($this->_quiz->id) ; |
| 324 | } |
| 325 | |
| 326 | if($neededNumber > $totalNumber)
|
| 327 | $neededNumber = $totalNumber ; |
| 328 | |
| 329 | $query = 'SELECT *' .
|
| 330 | ' FROM #__jquarks_questions AS questions' .
|
| 331 | ' WHERE questions.archived = 0' ;
|
| 332 | |
| 333 | if ($randomSet->category_id) {
|
| 334 | $query .= ' AND questions.category_id = ' . $randomSet->category_id ;
|
| 335 | } else {
|
| 336 | $query .= ' AND questions.category_id IS NULL';
|
| 337 | } |
| 338 | |
| 339 | if($questions && $customQuestions) {
|
| 340 | $query .= ' AND questions.id NOT IN (' . $customQuestions . ')' ; |
| 341 | } |
| 342 | |
| 343 | $randomQuestions = $this->_getList($query) ;
|
| 344 | if($this->_db->getErrorNum()) { |
| 345 | return false ; |
| 346 | } |
| 347 | |
| 348 | if ( $neededNumber > 1) |
| 349 | {
|
| 350 | $randomQuestionsKeys = array_rand($randomQuestions, $neededNumber) ; |
| 351 | |
| 352 | foreach ($randomQuestionsKeys as $key) { |
| 353 | $questions[] = $randomQuestions[$key] ; |
| 354 | } |
| 355 | } else {
|
| 356 | $questions[] = $randomQuestions[array_rand($randomQuestions,1)];
|
| 357 | } |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | $this->_questions = $questions ;
|
| 362 | |
| 363 | // Storing the user session
|
| 364 | if (!$this->storeSession()) { |
| 365 | return false ; |
| 366 | } |
| 367 | |
| 368 | return $this->_questions ; |
| 369 | } |
| 370 | |
| 371 | /**
|
| 372 | * Get the propositions of the retrieved questions |
| 373 | * |
| 374 | * @param $questions |
| 375 | * @return array |
| 376 | */ |
| 377 | function getPropositions($questions = null) |
| 378 | {
|
| 379 | if($questions)
|
| 380 | {
|
| 381 | foreach ($questions AS $key => $value)
|
| 382 | {
|
| 383 | $query = 'SELECT prop.answer, prop.id, prop.correct' .
|
| 384 | ' FROM #__jquarks_propositions AS prop' .
|
| 385 | ' LEFT JOIN #__jquarks_questions AS q ON q.id = prop.question_id' .
|
| 386 | ' WHERE prop.question_id = ' . $value ;
|
| 387 | |
| 388 | $this->_propositions[$value] = $this->_getList($query) ; |
| 389 | if ($this->_db->getErrorNum()) { |
| 390 | return false ; |
| 391 | } |
| 392 | } |
| 393 | } |
| 394 | else
|
| 395 | {
|
| 396 | foreach($this->_questions as $question) |
| 397 | {
|
| 398 | $query = 'SELECT prop.answer, prop.id, prop.correct' .
|
| 399 | ' FROM #__jquarks_propositions AS prop' .
|
| 400 | ' LEFT JOIN #__jquarks_questions AS q ON q.id = prop.question_id' .
|
| 401 | ' WHERE prop.question_id = ' . $question->id ;
|
| 402 | |
| 403 | $this->_propositions[$question->id] = $this->_getList($query) ; |
| 404 | if ($this->_db->getErrorNum()) { |
| 405 | return false ; |
| 406 | } |
| 407 | } |
| 408 | } |
| 409 | |
| 410 | return $this->_propositions ; |
| 411 | } |
| 412 | |
| 413 | /**
|
| 414 | * Return the selected session |
| 415 | * |
| 416 | * @return unknown_type |
| 417 | */ |
| 418 | private function getSession() |
| 419 | {
|
| 420 | $query = 'SELECT *' .
|
| 421 | ' FROM #__jquarks_quizsession' .
|
| 422 | ' WHERE id = ' . $this->_sessionId ; |
| 423 | |
| 424 | $this->_db->setQuery($query) ;
|
| 425 | $session = $this->_db->loadObject() ;
|
| 426 | if ($this->_db->getErrorNum()) { |
| 427 | return false ; |
| 428 | } |
| 429 | |
| 430 | return $session ;
|
| 431 | } |
| 432 | |
| 433 | /**
|
| 434 | * Store user information |
| 435 | * |
| 436 | * @return boolean |
| 437 | */ |
| 438 | private function storeUserInfo($sessionId) |
| 439 | {
|
| 440 | $userInfo['session_id'] = $sessionId ;
|
| 441 | $userInfo['user_id'] = $this->_user->id ; |
| 442 | |
| 443 | $userInfo['email'] = $this->_user->email ; |
| 444 | |
| 445 | $name = explode(" ", $this->_user->name); |
| 446 | |
| 447 | $userInfo['givenname'] = $name[0] ; |
| 448 | |
| 449 | if ( array_key_exists(1, $name) ) { |
| 450 | $userInfo['familyname'] = $name[1] ; |
| 451 | } else {
|
| 452 | $userInfo['familyname'] = "" ; |
| 453 | } |
| 454 | |
| 455 | return $this->sessionWhoTable->save($userInfo) ; |
| 456 | } |
| 457 | |
| 458 | /**
|
| 459 | * If a user has already taken a quiz, when he is unassigned from it his assignation is archived |
| 460 | * |
| 461 | * @todo dumplicated in back office. find a way to clean it |
| 462 | * @param $assignationId |
| 463 | * @return boolean |
| 464 | */ |
| 465 | function archiveAssignation($assignationId)
|
| 466 | {
|
| 467 | $query = 'UPDATE #__jquarks_users_quizzes AS users_quizzes' .
|
| 468 | ' SET archived = 1' .
|
| 469 | ' WHERE users_quizzes.id = ' . $assignationId ;
|
| 470 | |
| 471 | $this->_db->execute($query) ;
|
| 472 | if ($this->_db->getErrorNum()) { |
| 473 | return false; |
| 474 | } |
| 475 | |
| 476 | return true ; |
| 477 | } |
| 478 | |
| 479 | /**
|
| 480 | * UnassignUser unassign a specific user if the user have already took the quiz the assignation will be archived |
| 481 | * |
| 482 | * @todo this is a modified version of the function present in quiz model back office find a way to merge them and get rid of this one |
| 483 | * @return boolean |
| 484 | */ |
| 485 | function unassignUser($userId, $quizId)
|
| 486 | {
|
| 487 | $this->_users_quizzesTable =& JTable::getInstance('users_quizzes', 'Table') ; |
| 488 | |
| 489 | $line['quiz_id'] = (int)$quizId ;
|
| 490 | $line['user_id'] = $userId ;
|
| 491 | |
| 492 | // getting the id of the record to delete / archive
|
| 493 | $query = 'SELECT users_quizzes.id' .
|
| 494 | ' FROM #__jquarks_users_quizzes AS users_quizzes' .
|
| 495 | ' WHERE users_quizzes.quiz_id = ' . $line['quiz_id'] . |
| 496 | ' AND users_quizzes.user_id = ' . $line['user_id'] ; |
| 497 | |
| 498 | $this->_db->setQuery($query) ;
|
| 499 | |
| 500 | $assignationId = $this->_db->loadResult() ;
|
| 501 | if ($this->_db->getErrorNum()) { |
| 502 | return false ; |
| 503 | } |
| 504 | |
| 505 | return $this->archiveAssignation($assignationId) ; |
| 506 | } |
| 507 | |
| 508 | /**
|
| 509 | * Store the session's quiz |
| 510 | * |
| 511 | * @return boolean |
| 512 | */ |
| 513 | private function storeSession() |
| 514 | {
|
| 515 | $lineSession['id'] = 0 ; |
| 516 | |
| 517 | // getting the id of affectation
|
| 518 | $quizId = JRequest::getVar('id') ;
|
| 519 | $lineSession['affected_id'] = $this->getAffectedId($quizId) ; |
| 520 | |
| 521 | // If the quiz is of unique session unaffecting the user from the quiz
|
| 522 | /*if ((int)$this->_quiz->unique_session) {
|
| 523 | $this->unassignUser($this->_userId, $this->_quiz->id) ; |
| 524 | }*/ |
| 525 | |
| 526 | // getting local time offset from config. Start time when the quiz was generated to the user
|
| 527 | $config =& JFactory::getConfig(); |
| 528 | $jnow =& JFactory::getDate(); |
| 529 | $jnow->setOffset( $config->getValue('config.offset' ));
|
| 530 | $now = $jnow->toMySQL(true);
|
| 531 | |
| 532 | $lineSession['started_on'] = $now ;
|
| 533 | |
| 534 | // storing the ip address of the user
|
| 535 | $lineSession['ip_address'] = $_SERVER['REMOTE_ADDR']; |
| 536 | |
| 537 | // storing the questions
|
| 538 | $questions_id = array() ;
|
| 539 | foreach($this->_questions AS $question) { |
| 540 | $questions_id[] = $question->id ; |
| 541 | } |
| 542 | $lineSession['questions_id'] = implode(",", $questions_id); |
| 543 | |
| 544 | if(!$this->quizSessionTable->save($lineSession)) { |
| 545 | return false ; |
| 546 | } |
| 547 | |
| 548 | // getting the id of the session
|
| 549 | $query = 'SELECT id' .
|
| 550 | ' FROM #__jquarks_quizsession AS quizSession' .
|
| 551 | ' WHERE quizSession.affected_id = ' . $lineSession['affected_id'] . |
| 552 | ' AND quizSession.started_on = \''. $lineSession['started_on'] . '\'' ; |
| 553 | |
| 554 | $this->_db->setQuery($query) ;
|
| 555 | $this->_sessionId = $this->_db->loadResult() ; |
| 556 | if ($this->_db->getErrorNum()) |
| 557 | {
|
| 558 | echo $this->_db->stderr(); |
| 559 | return false ; |
| 560 | } |
| 561 | |
| 562 | // storing user's information
|
| 563 | if (!$this->storeUserInfo($this->_sessionId)) { |
| 564 | return false ; |
| 565 | } |
| 566 | |
| 567 | return true ; |
| 568 | } |
| 569 | |
| 570 | function getSessionId()
|
| 571 | {
|
| 572 | return $this->_sessionId ; |
| 573 | } |
| 574 | |
| 575 | /**
|
| 576 | * Get the number of seconds and return the corresponding hh:mm:ss time |
| 577 | * |
| 578 | * @param $time seconds |
| 579 | * @return string |
| 580 | */ |
| 581 | function secondsToTime($time)
|
| 582 | {
|
| 583 | $hours = (int)($time / 3600);
|
| 584 | $time = $time % 3600;
|
| 585 | $mins = (int)($time / 60);
|
| 586 | $seconds = $time % 60 ;
|
| 587 | |
| 588 | return sprintf('%02d:%02d:%02d', $hours, $mins, $seconds); |
| 589 | } |
| 590 | |
| 591 | |
| 592 | /**
|
| 593 | * Storing the answers provided by the user |
| 594 | * |
| 595 | * answer status |
| 596 | * -2 not anwsered |
| 597 | * -1 not reviewed (case of input type) |
| 598 | * 0 incorrect |
| 599 | * 1 correct |
| 600 | * 2 omitted |
| 601 | * |
| 602 | * @return boolean |
| 603 | * |
| 604 | */ |
| 605 | function storeAnswers()
|
| 606 | {
|
| 607 | $answers = JRequest::getVar('answers', 0, '', 'array') ; |
| 608 | $this->_sessionId = JRequest::getVar('sessionId') ; |
| 609 | |
| 610 | $questions = $this->getSessionQuestions() ;
|
| 611 | |
| 612 | // if the session is unique we unassign the user
|
| 613 | $this->getQuiz($this->_id); |
| 614 | if ((int)$this->_quiz->unique_session) { |
| 615 | $this->unassignUser($this->_user->id, $this->_id) ; |
| 616 | } |
| 617 | |
| 618 | // building an array with the questions ids
|
| 619 | $questions = explode(",", $questions);
|
| 620 | |
| 621 | // getting the propositions for those questions
|
| 622 | $this->_propositions = $this->getPropositions($questions); |
| 623 | |
| 624 | foreach ($this->_propositions as $question_id => $propositions) |
| 625 | {
|
| 626 | // emptying the arrays for the new iteration
|
| 627 | $answerAll = array() ;
|
| 628 | $answerLine = array() ;
|
| 629 | |
| 630 | $answerLine['id'] = 0 ; |
| 631 | $answerLine['quizsession_id'] = $this->_sessionId ; |
| 632 | $answerLine['question_id'] = $question_id ;
|
| 633 | $answerLine['altanswer'] = '' ; |
| 634 | $answerLine['answer_id'] = '' ; |
| 635 | $answerLine['score'] = 0.0 ; |
| 636 | |
| 637 | if (array_key_exists($question_id, $answers))
|
| 638 | {
|
| 639 | // the user answered this question
|
| 640 | // $answer contain either the value of the answer or an array if the question is a multiple answers one
|
| 641 | $answer = $answers[$question_id] ; |
| 642 | |
| 643 | if (!$propositions) // case of an input question we have no proposition for this question |
| 644 | {
|
| 645 | $answerLine['altanswer'] = $answer ;
|
| 646 | $answerLine['status'] = -1 ; |
| 647 | $answerLine['score'] = -1 ; |
| 648 | |
| 649 | $answerAll[] = $answerLine ; |
| 650 | } |
| 651 | elseif (is_array($answer)) // case of a checkbox multiple answers |
| 652 | {
|
| 653 | $checkBoxes[] = array() ;
|
| 654 | |
| 655 | $i = $correctNumber = 0 ;
|
| 656 | $score = 0.0 ; |
| 657 | foreach ($propositions as $proposition) |
| 658 | {
|
| 659 | $checkBoxes[$i]["id"] = $proposition->id ;
|
| 660 | $checkBoxes[$i]["correct"] = $proposition->correct ? true : false ; |
| 661 | $checkBoxes[$i]["checked"] = array_key_exists($proposition->id, $answer) ? true : false ; |
| 662 | |
| 663 | if ($checkBoxes[$i]["correct"] && $checkBoxes[$i]["checked"]) { |
| 664 | $score++ ; |
| 665 | } |
| 666 | |
| 667 | if (!$checkBoxes[$i]["correct"] && $checkBoxes[$i]["checked"]) { |
| 668 | $score-- ; |
| 669 | } |
| 670 | |
| 671 | if ($checkBoxes[$i]["correct"]) { |
| 672 | $correctNumber++ ; |
| 673 | } |
| 674 | |
| 675 | $i++ ; |
| 676 | } |
| 677 | |
| 678 | $answerLine['score'] = (float)$score / $correctNumber ;
|
| 679 | if ($answerLine['score'] < 0) { // we do not allow the score to be negeative |
| 680 | $answerLine['score'] = 0 ; |
| 681 | } |
| 682 | |
| 683 | foreach ($checkBoxes AS $key => $value)
|
| 684 | {
|
| 685 | $answerLine['answer_id'] = $value['id'] ; |
| 686 | |
| 687 | if ($value['checked'] && $value['correct']) |
| 688 | {
|
| 689 | $answerLine['status'] = 1 ; // answer is correct |
| 690 | $answerAll[] = $answerLine ; |
| 691 | $answerLine['score'] = 0.0 ; |
| 692 | } |
| 693 | |
| 694 | if ($value['checked'] && !$value['correct']) |
| 695 | {
|
| 696 | $answerLine['status'] = 0 ; // answer is incorrect |
| 697 | $answerAll[] = $answerLine ; |
| 698 | $answerLine['score'] = 0.0 ; |
| 699 | } |
| 700 | |
| 701 | if (!$value['checked'] && $value['correct']) |
| 702 | {
|
| 703 | // 2 proposition is correct but user didn't check it (omitted)
|
| 704 | $answerLine['status'] = 2 ; |
| 705 | $answerAll[] = $answerLine ; |
| 706 | $answerLine['score'] = 0.0 ; |
| 707 | } |
| 708 | } |
| 709 | } |
| 710 | else // case of a unique radio answer |
| 711 | {
|
| 712 | foreach ($propositions as $proposition) |
| 713 | {
|
| 714 | if ($proposition->id == $answer)
|
| 715 | {
|
| 716 | if ($proposition->correct) {
|
| 717 | $answerLine['score'] = $answerLine['status'] = 1 ; |
| 718 | } else {
|
| 719 | $answerLine['score'] = $answerLine['status'] = 0 ; |
| 720 | } |
| 721 | break ;
|
| 722 | } |
| 723 | } |
| 724 | $answerLine['answer_id'] = $answer ;
|
| 725 | |
| 726 | $answerAll[] = $answerLine ; |
| 727 | } |
| 728 | } |
| 729 | else // the question wasn't answered by the user |
| 730 | {
|
| 731 | $answerLine['status'] = -2 ; |
| 732 | $answerAll[] = $answerLine ; |
| 733 | } |
| 734 | |
| 735 | foreach($answerAll as $answer) |
| 736 | {
|
| 737 | if (!$this->quizAnswerTable->save($answer)) { |
| 738 | return false ; |
| 739 | } |
| 740 | } |
| 741 | } |
| 742 | |
| 743 | // Updating the finishing time of the session
|
| 744 | $lineSession['id'] = $this->_sessionId ; |
| 745 | |
| 746 | $session = $this->getSession() ;
|
| 747 | |
| 748 | $config =& JFactory::getConfig(); |
| 749 | $jnow =& JFactory::getDate(); |
| 750 | $jnow->setOffset( $config->getValue('config.offset' ));
|
| 751 | $now = $jnow->toMySQL(true);
|
| 752 | $lineSession['finished_on'] = $now ;
|
| 753 | |
| 754 | $lineSession['spent_time'] = strtotime($lineSession['finished_on']) - strtotime($session->started_on) ; |
| 755 | $lineSession['spent_time'] = $this->secondsToTime($lineSession['spent_time']) ; |
| 756 | |
| 757 | if (!$this->quizSessionTable->save($lineSession)) { |
| 758 | return false ; |
| 759 | } |
| 760 | |
| 761 | return true ; |
| 762 | } |
| 763 | |
| 764 | } |