1<?php 2/* 3 +-----------------------------------------------------------------------------+ 4 | ILIAS open source | 5 +-----------------------------------------------------------------------------+ 6 | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | 7 | | 8 | This program is free software; you can redistribute it and/or | 9 | modify it under the terms of the GNU General Public License | 10 | as published by the Free Software Foundation; either version 2 | 11 | of the License, or (at your option) any later version. | 12 | | 13 | This program is distributed in the hope that it will be useful, | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 | GNU General Public License for more details. | 17 | | 18 | You should have received a copy of the GNU General Public License | 19 | along with this program; if not, write to the Free Software | 20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 21 +-----------------------------------------------------------------------------+ 22*/ 23 24/** 25* @author Stefan Meyer <meyer@leifos.com> 26* 27* @version $Id$ 28* 29* @package ilias-tracking 30* 31*/ 32 33include_once './Services/Tracking/classes/class.ilLPStatus.php'; 34 35class ilLPStatusTestPassed extends ilLPStatus 36{ 37 public function __construct($a_obj_id) 38 { 39 global $DIC; 40 41 $ilDB = $DIC['ilDB']; 42 43 parent::__construct($a_obj_id); 44 $this->db = $ilDB; 45 } 46 47 public static function _getInProgress($a_obj_id) 48 { 49 global $DIC; 50 51 $ilBench = $DIC['ilBench']; 52 53 $ilBench->start('LearningProgress', '9182_LPStatusTestPassed_inProgress'); 54 $userIds = self::getUserIdsByResultArrayStatus($a_obj_id, 'in_progress'); 55 $ilBench->stop('LearningProgress', '9182_LPStatusTestPassed_inProgress'); 56 57 return $userIds; 58 } 59 60 public static function _getCompleted($a_obj_id) 61 { 62 global $DIC; 63 64 $ilBench = $DIC['ilBench']; 65 66 $ilBench->start('LearningProgress', '9183_LPStatusTestPassed_completed'); 67 $userIds = self::getUserIdsByResultArrayStatus($a_obj_id, 'passed'); 68 $ilBench->stop('LearningProgress', '9183_LPStatusTestPassed_completed'); 69 70 return $userIds; 71 } 72 73 public static function _getNotAttempted($a_obj_id) 74 { 75 return self::getUserIdsByResultArrayStatus($a_obj_id, 'not_attempted'); 76 } 77 78 public static function _getFailed($a_obj_id) 79 { 80 return self::getUserIdsByResultArrayStatus($a_obj_id, 'failed'); 81 } 82 83 private static function getUserIdsByResultArrayStatus($objId, $resultArrayStatus) 84 { 85 $status_info = ilLPStatusWrapper::_getStatusInfo($objId); 86 87 $user_ids = array(); 88 89 foreach ($status_info['results'] as $user_data) { 90 if ($user_data[$resultArrayStatus]) { 91 $user_ids[] = $user_data['user_id']; 92 } 93 } 94 95 return $user_ids; 96 } 97 98 public static function _getStatusInfo($a_obj_id) 99 { 100 include_once './Modules/Test/classes/class.ilObjTestAccess.php'; 101 $status_info['results'] = ilObjTestAccess::_getPassedUsers($a_obj_id); 102 return $status_info; 103 } 104 105 /** 106 * Determine status. 107 * 108 * Behaviour of "old" 4.0 learning progress: 109 * 110 * Setting "Multiple Pass Scoring": Score the last pass 111 * - Test not started: No entry 112 * - First question opened: Icon/Text: Failed, Score 0% 113 * - First question answered (correct, points enough for passing): Icon/Text: Completed, Score 66% 114 * - No change after successfully finishing the pass. (100%) 115 * - 2nd Pass, first question opened: Still Completed/Completed 116 * - First question answered (incorrect, success possible): Icon/Text Failed, Score 33% 117 * - Second question answered (correct): Icon/Text completed 118 * - 3rd pass, like 2nd, but two times wrong answer: Icon/Text: Failed 119 * 120 * Setting "Multiple Pass Scoring": Score the best pass 121 * - Test not started: No entry 122 * - First question opened: Icon/Text: Failed, Score 0% 123 * - First question answered (correct, points enough for passing): Icon/Text: Completed, Score 66% 124 * - No change after successfully finishing the pass. (100%) 125 * - 2nd Pass, first question opened: Still Completed/Completed 126 * - First question answered (incorrect, success possible): Still Completed/Completed 127 * 128 * Due to this behaviour in 4.0 we do not have a "in progress" status. During the test 129 * the status is "failed" unless the score is enough to pass the test, which makes the 130 * learning progress status "completed". 131 * 132 * @param integer object id 133 * @param integer user id 134 * @param object object (optional depends on object type) 135 * @return integer status 136 */ 137 public function determineStatus($a_obj_id, $a_user_id, $a_obj = null) 138 { 139 global $DIC; 140 141 $ilDB = $DIC['ilDB']; 142 143 $status = self::LP_STATUS_NOT_ATTEMPTED_NUM; 144 require_once 'Modules/Test/classes/class.ilObjTestAccess.php'; 145 $res = $ilDB->query(" 146 SELECT tst_active.active_id, tst_active.tries, count(tst_sequence.active_fi) " . $ilDB->quoteIdentifier("sequences") . ", tst_active.last_finished_pass, 147 CASE WHEN 148 (tst_tests.nr_of_tries - 1) = tst_active.last_finished_pass 149 THEN '1' 150 ELSE '0' 151 END is_last_pass 152 FROM tst_active 153 LEFT JOIN tst_sequence 154 ON tst_sequence.active_fi = tst_active.active_id 155 LEFT JOIN tst_tests 156 ON tst_tests.test_id = tst_active.test_fi 157 WHERE tst_active.user_fi = {$ilDB->quote($a_user_id, "integer")} 158 AND tst_active.test_fi = {$ilDB->quote(ilObjTestAccess::_getTestIDFromObjectID($a_obj_id))} 159 GROUP BY tst_active.active_id, tst_active.tries, is_last_pass 160 "); 161 162 if ($rec = $ilDB->fetchAssoc($res)) { 163 if ($rec['sequences'] > 0) { 164 require_once 'Modules/Test/classes/class.ilObjTest.php'; 165 166 $test_obj = new ilObjTest($a_obj_id, false); 167 $is_passed = ilObjTestAccess::_isPassed($a_user_id, $a_obj_id); 168 169 if ($test_obj->getPassScoring() == SCORE_LAST_PASS) { 170 $is_finished = false; 171 if ($rec['last_finished_pass'] != null && $rec['sequences'] - 1 == $rec['last_finished_pass']) { 172 $is_finished = true; 173 } 174 $status = $this->determineStatusForScoreLastPassTests($is_finished, $is_passed); 175 } elseif ($test_obj->getPassScoring() == SCORE_BEST_PASS) { 176 $status = self::LP_STATUS_IN_PROGRESS_NUM; 177 178 if ($rec['last_finished_pass'] != null) { 179 $status = $this->determineLpStatus($is_passed); 180 } 181 182 if (!$rec['is_last_pass'] && $status == self::LP_STATUS_FAILED_NUM) { 183 $status = self::LP_STATUS_IN_PROGRESS_NUM; 184 } 185 } 186 } 187 } 188 189 return $status; 190 } 191 192 /** 193 * @param $is_finished 194 * @param $passed 195 * @return int 196 */ 197 protected function determineStatusForScoreLastPassTests($is_finished, $passed) 198 { 199 $status = self::LP_STATUS_IN_PROGRESS_NUM; 200 201 if ($is_finished) { 202 $status = $this->determineLpStatus($passed); 203 } 204 205 return $status; 206 } 207 208 /** 209 * @param $passed 210 * @return int 211 */ 212 protected function determineLpStatus($passed) 213 { 214 $status = self::LP_STATUS_FAILED_NUM; 215 216 if ($passed) { 217 $status = self::LP_STATUS_COMPLETED_NUM; 218 } 219 220 return $status; 221 } 222 223 /** 224 * Determine percentage 225 * 226 * @param integer object id 227 * @param integer user id 228 * @param object object (optional depends on object type) 229 * @return integer percentage 230 */ 231 public function determinePercentage($a_obj_id, $a_user_id, $a_obj = null) 232 { 233 global $DIC; 234 235 $ilDB = $DIC['ilDB']; 236 237 $set = $ilDB->query("SELECT tst_result_cache.*, tst_active.user_fi FROM " . 238 "tst_result_cache JOIN tst_active ON (tst_active.active_id = tst_result_cache.active_fi)" . 239 " JOIN tst_tests ON (tst_tests.test_id = tst_active.test_fi) " . 240 " WHERE tst_tests.obj_fi = " . $ilDB->quote($a_obj_id, "integer") . 241 " AND tst_active.user_fi = " . $ilDB->quote($a_user_id, "integer")); 242 $per = 0; 243 if ($rec = $ilDB->fetchAssoc($set)) { 244 if ($rec["max_points"] > 0) { 245 $per = min(100, 100 / $rec["max_points"] * $rec["reached_points"]); 246 } else { 247 // According to mantis #12305 248 $per = 0; 249 } 250 } 251 return (int) $per; 252 } 253} 254