ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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(ilDBInterface $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 $this->questions[] = $questionData['question_id'];
178
179 $this->maxPointsByQuestion[ $questionData['question_id'] ] = $questionData['points'];
180 }
181 }
182
186 private function initTestResultData($testResults)
187 {
188 foreach ($testResults as $key => $result) {
189 if ($key === 'pass' || $key === 'test') { // note: key int 0 IS == 'pass' or 'buxtehude'
190 continue;
191 }
192
193 if (!$result['workedthrough']) {
194 continue;
195 }
196
197 $this->reachedPointsByQuestion[ $result['qid'] ] = $result['reached'];
198 }
199 }
200
201 private function drawUpSkillPointAccounts()
202 {
203 foreach ($this->questions as $questionId) {
204 if (!$this->isAnsweredQuestion($questionId)) {
205 continue;
206 }
207
208 $assignments = $this->skillQuestionAssignmentList->getAssignmentsByQuestionId($questionId);
209
210 foreach ($assignments as $assignment) {
211 if ($assignment->hasEvalModeBySolution()) {
212 $reachedSkillPoints = $this->determineReachedSkillPointsWithSolutionCompare(
213 $assignment->getSolutionComparisonExpressionList()
214 );
215 } else {
216 $maxTestPoints = $this->maxPointsByQuestion[$questionId];
217 $reachedTestPoints = $this->reachedPointsByQuestion[$questionId];
218
219 $reachedSkillPoints = $this->calculateReachedSkillPointsFromTestPoints(
220 $assignment->getSkillPoints(),
221 $maxTestPoints,
222 $reachedTestPoints
223 );
224 }
225
227 $assignment->getSkillBaseId(),
228 $assignment->getSkillTrefId(),
229 $assignment->getMaxSkillPoints(),
230 $reachedSkillPoints
231 );
232 }
233 }
234 }
235
236 private function isAnsweredQuestion($questionId)
237 {
238 return isset($this->reachedPointsByQuestion[$questionId]);
239 }
240
242 {
243 $questionProvider = new ilAssLacQuestionProvider();
244 $questionProvider->setQuestionId($expressionList->getQuestionId());
245
246 foreach ($expressionList->get() as $expression) {
247 /* @var ilAssQuestionSolutionComparisonExpression $expression */
248
249 $conditionParser = new ilAssLacConditionParser();
250 $conditionComposite = $conditionParser->parse($expression->getExpression());
251
252 $compositeEvaluator = new ilAssLacCompositeEvaluator(
253 $questionProvider,
254 $this->getActiveId(),
255 $this->getPass()
256 );
257
258 if ($compositeEvaluator->evaluate($conditionComposite)) {
259 return $expression->getPoints();
260 }
261 }
262
263 return 0;
264 }
265
266 private function calculateReachedSkillPointsFromTestPoints($skillPoints, $maxTestPoints, $reachedTestPoints)
267 {
268 if ($reachedTestPoints < 0) {
269 $reachedTestPoints = 0;
270 }
271
272 $factor = 0;
273
274 if ($maxTestPoints > 0) {
275 $factor = $reachedTestPoints / $maxTestPoints;
276 }
277
278 return ($skillPoints * $factor);
279 }
280
281 private function bookToSkillPointAccount($skillBaseId, $skillTrefId, $maxSkillPoints, $reachedSkillPoints)
282 {
283 $skillKey = $skillBaseId . ':' . $skillTrefId;
284
285 if (!isset($this->skillPointAccounts[$skillKey])) {
286 $this->skillPointAccounts[$skillKey] = new ilTestSkillPointAccount();
287 }
288
289 $this->skillPointAccounts[$skillKey]->addBooking($maxSkillPoints, $reachedSkillPoints);
290 }
291
292 private function evaluateSkillPointAccounts()
293 {
294 foreach ($this->skillPointAccounts as $skillKey => $skillPointAccount) {
295 /* @var ilTestSkillPointAccount $skillPointAccount */
296
297 if (!$this->doesNumBookingsExceedRequiredBookingsBarrier($skillPointAccount)) {
298 continue;
299 }
300
301 list($skillBaseId, $skillTrefId) = explode(':', $skillKey);
302
303 $skill = new ilBasicSkill($skillBaseId);
304 $levels = $skill->getLevelData();
305
306 $reachedLevelId = null;
307
308 foreach ($levels as $level) {
309 $threshold = $this->skillLevelThresholdList->getThreshold($skillBaseId, $skillTrefId, $level['id']);
310
311 if (!($threshold instanceof ilTestSkillLevelThreshold) || !$threshold->getThreshold()) {
312 continue;
313 }
314
315 $reachedLevelId = $level['id'];
316
317 if ($skillPointAccount->getTotalReachedSkillPercent() <= $threshold->getThreshold()) {
318 break;
319 }
320 }
321
322 if ($reachedLevelId) {
323 $this->reachedSkillLevels[] = array(
324 'sklBaseId' => $skillBaseId, 'sklTrefId' => $skillTrefId, 'sklLevelId' => $reachedLevelId
325 );
326 }
327 }
328 }
329
331 {
332 return $skillPointAccount->getNumBookings() >= $this->getNumRequiredBookingsForSkillTriggering();
333 }
334
335 public function handleSkillTriggering()
336 {
337 foreach ($this->getReachedSkillLevels() as $reachedSkillLevel) {
338 $this->invokeSkillLevelTrigger($reachedSkillLevel['sklLevelId'], $reachedSkillLevel['sklTrefId']);
339 }
340 }
341
342 private function invokeSkillLevelTrigger($skillLevelId, $skillTrefId)
343 {
345 $skillLevelId,
346 $this->getUserId(),
347 $this->refId,
348 $skillTrefId,
350 true,
351 0,
352 $this->getPass()
353 );
354
355 /* @var ILIAS\DI\Container $DIC */ global $DIC;
356
357 $DIC->logger()->root()->info(
358 "refId={$this->refId} / usrId={$this->getUserId()} / levelId={$skillLevelId} / trefId={$skillTrefId}"
359 );
360
361 //mail('bheyser@databay.de', "trigger skill level $skillLevelId for user {$this->getUserId()}", '');
362 }
363
365 {
366 $skillsMatchingNumAnswersBarrier = array();
367
368 foreach ($this->skillPointAccounts as $skillKey => $skillPointAccount) {
369 if ($this->doesNumBookingsExceedRequiredBookingsBarrier($skillPointAccount)) {
370 list($skillBaseId, $skillTrefId) = explode(':', $skillKey);
371
372 $skillsMatchingNumAnswersBarrier[$skillKey] = array(
373 'base_skill_id' => (int) $skillBaseId,
374 'tref_id' => (int) $skillTrefId
375 );
376 }
377 }
378
379 return $skillsMatchingNumAnswersBarrier;
380 }
381
383 {
384 $uniqueSkills = array();
385
386 foreach ($this->skillQuestionAssignmentList->getUniqueAssignedSkills() as $skill) {
387 $skillKey = $skill['skill_base_id'] . ':' . $skill['skill_tref_id'];
388
389 $uniqueSkills[$skillKey] = array(
390 'base_skill_id' => (int) $skill['skill_base_id'],
391 'tref_id' => (int) $skill['skill_tref_id']
392 );
393 }
394
395 return $uniqueSkills;
396 }
397
398 public function isAssignedSkill($skillBaseId, $skillTrefId)
399 {
400 $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId);
401 }
402
404 {
405 $matchingSkillProfiles = array();
406
407 include_once("./Services/Skill/classes/class.ilSkillProfile.php");
408 $usersProfiles = ilSkillProfile::getProfilesOfUser($this->getUserId());
409
410 foreach ($usersProfiles as $profileData) {
411 $profile = new ilSkillProfile($profileData['id']);
412 $assignedSkillLevels = $profile->getSkillLevels();
413
414 foreach ($assignedSkillLevels as $assignedSkillLevel) {
415 $skillBaseId = $assignedSkillLevel['base_skill_id'];
416 $skillTrefId = $assignedSkillLevel['tref_id'];
417
418 if ($this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId)) {
419 $matchingSkillProfiles[$profileData['id']] = $profile->getTitle();
420 }
421 }
422 }
423
424 return $matchingSkillProfiles;
425 }
426
427 public function noProfileMatchingAssignedSkillExists($availableSkillProfiles)
428 {
429 $noProfileMatchingSkills = $this->skillQuestionAssignmentList->getUniqueAssignedSkills();
430
431 foreach ($availableSkillProfiles as $skillProfileId => $skillProfileTitle) {
432 $profile = new ilSkillProfile($skillProfileId);
433 $assignedSkillLevels = $profile->getSkillLevels();
434
435 foreach ($assignedSkillLevels as $assignedSkillLevel) {
436 $skillBaseId = $assignedSkillLevel['base_skill_id'];
437 $skillTrefId = $assignedSkillLevel['tref_id'];
438
439 if ($this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId)) {
440 unset($noProfileMatchingSkills["{$skillBaseId}:{$skillTrefId}"]);
441 }
442 }
443 }
444
445 return count($noProfileMatchingSkills);
446 }
447}
$result
An exception for terminatinating execution or to throw for unit testing.
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=false, $a_unique_identifier="")
Write skill level status.
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(ilDBInterface $db, $testId, $refId)
$key
Definition: croninfo.php:18
Interface ilDBInterface.
global $DIC
Definition: saml.php:7