ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.ilTestSkillEvaluation.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
5require_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/ilAssLacQuestionProvider.php';
6require_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/ilAssLacConditionParser.php';
7require_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/ilAssLacCompositeEvaluator.php';
8require_once 'Modules/Test/classes/class.ilTestSkillPointAccount.php';
9require_once 'Modules/Test/classes/class.ilTestSkillLevelThresholdList.php';
10require_once 'Services/Skill/classes/class.ilBasicSkill.php';
11
19{
23 private $db;
24
28 private $refId;
29
34
39
43 private $questions;
44
49
54
59
64
68 private $userId;
69
73 private $activeId;
74
78 private $pass;
79
84
85 public function __construct(ilDB $db, $testId, $refId)
86 {
87 $this->db = $db;
88 $this->refId = $refId;
89
90 $this->skillQuestionAssignmentList = new ilAssQuestionSkillAssignmentList($this->db);
91
92 $this->skillLevelThresholdList = new ilTestSkillLevelThresholdList($this->db);
93 $this->skillLevelThresholdList->setTestId($testId);
94
95 $this->questions = array();
96 $this->maxPointsByQuestion = array();
97 }
98
99 public function getUserId()
100 {
101 return $this->userId;
102 }
103
104 public function setUserId($userId)
105 {
106 $this->userId = $userId;
107 }
108
109 public function getActiveId()
110 {
111 return $this->activeId;
112 }
113
114 public function setActiveId($activeId)
115 {
116 $this->activeId = $activeId;
117 }
118
119 public function getPass()
120 {
121 return $this->pass;
122 }
123
124 public function setPass($pass)
125 {
126 $this->pass = $pass;
127 }
128
130 {
132 }
133
135 {
136 $this->numRequiredBookingsForSkillTriggering = $numRequiredBookingsForSkillTriggering;
137 }
138
139 public function init(ilAssQuestionList $questionList)
140 {
141 $this->skillQuestionAssignmentList->setParentObjId($questionList->getParentObjId());
142 $this->skillQuestionAssignmentList->loadFromDb();
143
144 $this->skillLevelThresholdList->loadFromDb();
145
146 $this->initTestQuestionData($questionList);
147 }
148
152 public function evaluate($testResults)
153 {
154 $this->reset();
155
156 $this->initTestResultData($testResults);
157
160 }
161
162 public function getReachedSkillLevels()
163 {
165 }
166
167 private function reset()
168 {
169 $this->reachedPointsByQuestion = array();
170 $this->skillPointAccounts = array();
171 $this->reachedSkillLevels = array();
172 }
173
174 private function initTestQuestionData(ilAssQuestionList $questionList)
175 {
176 foreach($questionList->getQuestionDataArray() as $questionData)
177 {
178 $this->questions[] = $questionData['question_id'];
179
180 $this->maxPointsByQuestion[ $questionData['question_id'] ] = $questionData['points'];
181 }
182 }
183
187 private function initTestResultData($testResults)
188 {
189 foreach($testResults as $key => $result)
190 {
191 if($key === 'pass' || $key === 'test') // note: key int 0 IS == 'pass' or 'buxtehude'
192 {
193 continue;
194 }
195
196 if( !$result['workedthrough'] )
197 {
198 continue;
199 }
200
201 $this->reachedPointsByQuestion[ $result['qid'] ] = $result['reached'];
202 }
203 }
204
205 private function drawUpSkillPointAccounts()
206 {
207 foreach($this->questions as $questionId)
208 {
209 if( !$this->isAnsweredQuestion($questionId) )
210 {
211 continue;
212 }
213
214 $assignments = $this->skillQuestionAssignmentList->getAssignmentsByQuestionId($questionId);
215
216 foreach($assignments as $assignment)
217 {
218 if( $assignment->hasEvalModeBySolution() )
219 {
220 $reachedSkillPoints = $this->determineReachedSkillPointsWithSolutionCompare(
221 $assignment->getSolutionComparisonExpressionList()
222 );
223 }
224 else
225 {
226 $maxTestPoints = $this->maxPointsByQuestion[$questionId];
227 $reachedTestPoints = $this->reachedPointsByQuestion[$questionId];
228
229 $reachedSkillPoints = $this->calculateReachedSkillPointsFromTestPoints(
230 $assignment->getSkillPoints(), $maxTestPoints, $reachedTestPoints
231 );
232 }
233
235 $assignment->getSkillBaseId(), $assignment->getSkillTrefId(),
236 $assignment->getMaxSkillPoints(), $reachedSkillPoints
237 );
238 }
239 }
240 }
241
242 private function isAnsweredQuestion($questionId)
243 {
244 return isset($this->reachedPointsByQuestion[$questionId]);
245 }
246
248 {
249 $questionProvider = new ilAssLacQuestionProvider();
250 $questionProvider->setQuestionId($expressionList->getQuestionId());
251
252 foreach($expressionList->get() as $expression)
253 {
254 /* @var ilAssQuestionSolutionComparisonExpression $expression */
255
256 $conditionParser = new ilAssLacConditionParser();
257 $conditionComposite = $conditionParser->parse($expression->getExpression());
258
259 $compositeEvaluator = new ilAssLacCompositeEvaluator(
260 $questionProvider, $this->getActiveId(), $this->getPass()
261 );
262
263 if( $compositeEvaluator->evaluate($conditionComposite) )
264 {
265 return $expression->getPoints();
266 }
267 }
268
269 return 0;
270 }
271
272 private function calculateReachedSkillPointsFromTestPoints($skillPoints, $maxTestPoints, $reachedTestPoints)
273 {
274 if( $reachedTestPoints < 0 )
275 {
276 $reachedTestPoints = 0;
277 }
278
279 $factor = 0;
280
281 if( $maxTestPoints > 0 )
282 {
283 $factor = $reachedTestPoints / $maxTestPoints;
284 }
285
286 return ($skillPoints * $factor);
287 }
288
289 private function bookToSkillPointAccount($skillBaseId, $skillTrefId, $maxSkillPoints, $reachedSkillPoints)
290 {
291 $skillKey = $skillBaseId.':'.$skillTrefId;
292
293 if( !isset($this->skillPointAccounts[$skillKey]) )
294 {
295 $this->skillPointAccounts[$skillKey] = new ilTestSkillPointAccount();
296 }
297
298 $this->skillPointAccounts[$skillKey]->addBooking($maxSkillPoints, $reachedSkillPoints);
299 }
300
301 private function evaluateSkillPointAccounts()
302 {
303 foreach($this->skillPointAccounts as $skillKey => $skillPointAccount)
304 {
305 /* @var ilTestSkillPointAccount $skillPointAccount */
306
307 if( !$this->doesNumBookingsExceedRequiredBookingsBarrier($skillPointAccount) )
308 {
309 continue;
310 }
311
312 list($skillBaseId, $skillTrefId) = explode(':', $skillKey);
313
314 $skill = new ilBasicSkill($skillBaseId);
315 $levels = $skill->getLevelData();
316
317 $reachedLevelId = null;
318
319 foreach($levels as $level)
320 {
321 $threshold = $this->skillLevelThresholdList->getThreshold($skillBaseId, $skillTrefId, $level['id']);
322
323 if( !($threshold instanceof ilTestSkillLevelThreshold) || !$threshold->getThreshold() )
324 {
325 continue;
326 }
327
328 $reachedLevelId = $level['id'];
329
330 if( $skillPointAccount->getTotalReachedSkillPercent() <= $threshold->getThreshold() )
331 {
332 break;
333 }
334 }
335
336 if( $reachedLevelId )
337 {
338 $this->reachedSkillLevels[] = array(
339 'sklBaseId' => $skillBaseId, 'sklTrefId' => $skillTrefId, 'sklLevelId' => $reachedLevelId
340 );
341 }
342 }
343 }
344
346 {
347 return $skillPointAccount->getNumBookings() >= $this->getNumRequiredBookingsForSkillTriggering();
348 }
349
350 public function handleSkillTriggering()
351 {
352 foreach($this->getReachedSkillLevels() as $reachedSkillLevel)
353 {
354 $this->invokeSkillLevelTrigger($reachedSkillLevel['sklLevelId'], $reachedSkillLevel['sklTrefId']);
355 }
356 }
357
358 private function invokeSkillLevelTrigger($skillLevelId, $skillTrefId)
359 {
361 $skillLevelId, $this->getUserId(), $this->refId,
362 $skillTrefId, ilBasicSkill::ACHIEVED, true, 0, $this->getPass()
363 );
364
365 //mail('bheyser@databay.de', "trigger skill level $skillLevelId for user {$this->getUserId()}", '');
366 }
367
369 {
370 $reachedLevels = array();
371
372 foreach($this->getReachedSkillLevels() as $reachedLevel)
373 {
374 $reachedLevels[$reachedLevel['sklBaseId']] = array(
375 $reachedLevel['sklTrefId'] => $reachedLevel['sklLevelId']
376 );
377 }
378
379 return $reachedLevels;
380 }
381
383 {
384 $uniqueSkills = array();
385
386 foreach($this->skillQuestionAssignmentList->getUniqueAssignedSkills() as $skill)
387 {
388 $uniqueSkills[] = array(
389 'base_skill_id' => (int)$skill['skill_base_id'],
390 'tref_id' => (int)$skill['skill_tref_id']
391 );
392 }
393
394 return $uniqueSkills;
395 }
396
397 public function isAssignedSkill($skillBaseId, $skillTrefId)
398 {
399 $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId);
400 }
401
403 {
404 $matchingSkillProfiles = array();
405
406 include_once("./Services/Skill/classes/class.ilSkillProfile.php");
407 $usersProfiles = ilSkillProfile::getProfilesOfUser($this->getUserId());
408
409 foreach ($usersProfiles as $profileData)
410 {
411 $profile = new ilSkillProfile($profileData['id']);
412 $assignedSkillLevels = $profile->getSkillLevels();
413
414 foreach($assignedSkillLevels as $assignedSkillLevel)
415 {
416 $skillBaseId = $assignedSkillLevel['base_skill_id'];
417 $skillTrefId = $assignedSkillLevel['tref_id'];
418
419 if( $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId) )
420 {
421 $matchingSkillProfiles[$profileData['id']] = $profile->getTitle();
422 }
423 }
424 }
425
426 return $matchingSkillProfiles;
427 }
428
429 public function noProfileMatchingAssignedSkillExists($availableSkillProfiles)
430 {
431 $noProfileMatchingSkills = $this->skillQuestionAssignmentList->getUniqueAssignedSkills();
432
433 foreach($availableSkillProfiles as $skillProfileId => $skillProfileTitle)
434 {
435 $profile = new ilSkillProfile($skillProfileId);
436 $assignedSkillLevels = $profile->getSkillLevels();
437
438 foreach($assignedSkillLevels as $assignedSkillLevel)
439 {
440 $skillBaseId = $assignedSkillLevel['base_skill_id'];
441 $skillTrefId = $assignedSkillLevel['tref_id'];
442
443 if( $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId) )
444 {
445 unset($noProfileMatchingSkills["{$skillBaseId}:{$skillTrefId}"]);
446 }
447 }
448 }
449
450 return count($noProfileMatchingSkills);
451 }
452}
$result
Class ilParserQuestionProvider.
static writeUserSkillLevelStatus($a_level_id, $a_user_id, $a_trigger_ref_id, $a_tref_id=0, $a_status=ilBasicSkill::ACHIEVED, $a_force=false, $a_self_eval=0, $a_unique_identifier="")
Write skill level status.
Database Wrapper.
Definition: class.ilDB.php:29
static getProfilesOfUser($a_user_id)
Get profiles of a user.
init(ilAssQuestionList $questionList)
initTestQuestionData(ilAssQuestionList $questionList)
calculateReachedSkillPointsFromTestPoints($skillPoints, $maxTestPoints, $reachedTestPoints)
determineReachedSkillPointsWithSolutionCompare(ilAssQuestionSolutionComparisonExpressionList $expressionList)
setNumRequiredBookingsForSkillTriggering($numRequiredBookingsForSkillTriggering)
noProfileMatchingAssignedSkillExists($availableSkillProfiles)
isAssignedSkill($skillBaseId, $skillTrefId)
bookToSkillPointAccount($skillBaseId, $skillTrefId, $maxSkillPoints, $reachedSkillPoints)
invokeSkillLevelTrigger($skillLevelId, $skillTrefId)
doesNumBookingsExceedRequiredBookingsBarrier(ilTestSkillPointAccount $skillPointAccount)
__construct(ilDB $db, $testId, $refId)