ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 
4 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
5 require_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/ilAssLacQuestionProvider.php';
6 require_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/ilAssLacConditionParser.php';
7 require_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/ilAssLacCompositeEvaluator.php';
8 require_once 'Modules/Test/classes/class.ilTestSkillPointAccount.php';
9 require_once 'Modules/Test/classes/class.ilTestSkillLevelThresholdList.php';
10 require_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 
158  $this->drawUpSkillPointAccounts();
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  $skillsMatchingNumAnswersBarrier = array();
371 
372  foreach($this->skillPointAccounts as $skillKey => $skillPointAccount)
373  {
374  if( $this->doesNumBookingsExceedRequiredBookingsBarrier($skillPointAccount) )
375  {
376  list($skillBaseId, $skillTrefId) = explode(':', $skillKey);
377 
378  $skillsMatchingNumAnswersBarrier[$skillKey] = array(
379  'base_skill_id' => (int)$skillBaseId,
380  'tref_id' => (int)$skillTrefId
381  );
382  }
383  }
384 
385  return $skillsMatchingNumAnswersBarrier;
386  }
387 
389  {
390  $uniqueSkills = array();
391 
392  foreach($this->skillQuestionAssignmentList->getUniqueAssignedSkills() as $skill)
393  {
394  $skillKey = $skill['skill_base_id'].':'.$skill['skill_tref_id'];
395 
396  $uniqueSkills[$skillKey] = array(
397  'base_skill_id' => (int)$skill['skill_base_id'],
398  'tref_id' => (int)$skill['skill_tref_id']
399  );
400  }
401 
402  return $uniqueSkills;
403  }
404 
405  public function isAssignedSkill($skillBaseId, $skillTrefId)
406  {
407  $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId);
408  }
409 
411  {
412  $matchingSkillProfiles = array();
413 
414  include_once("./Services/Skill/classes/class.ilSkillProfile.php");
415  $usersProfiles = ilSkillProfile::getProfilesOfUser($this->getUserId());
416 
417  foreach ($usersProfiles as $profileData)
418  {
419  $profile = new ilSkillProfile($profileData['id']);
420  $assignedSkillLevels = $profile->getSkillLevels();
421 
422  foreach($assignedSkillLevels as $assignedSkillLevel)
423  {
424  $skillBaseId = $assignedSkillLevel['base_skill_id'];
425  $skillTrefId = $assignedSkillLevel['tref_id'];
426 
427  if( $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId) )
428  {
429  $matchingSkillProfiles[$profileData['id']] = $profile->getTitle();
430  }
431  }
432  }
433 
434  return $matchingSkillProfiles;
435  }
436 
437  public function noProfileMatchingAssignedSkillExists($availableSkillProfiles)
438  {
439  $noProfileMatchingSkills = $this->skillQuestionAssignmentList->getUniqueAssignedSkills();
440 
441  foreach($availableSkillProfiles as $skillProfileId => $skillProfileTitle)
442  {
443  $profile = new ilSkillProfile($skillProfileId);
444  $assignedSkillLevels = $profile->getSkillLevels();
445 
446  foreach($assignedSkillLevels as $assignedSkillLevel)
447  {
448  $skillBaseId = $assignedSkillLevel['base_skill_id'];
449  $skillTrefId = $assignedSkillLevel['tref_id'];
450 
451  if( $this->skillQuestionAssignmentList->isAssignedSkill($skillBaseId, $skillTrefId) )
452  {
453  unset($noProfileMatchingSkills["{$skillBaseId}:{$skillTrefId}"]);
454  }
455  }
456  }
457 
458  return count($noProfileMatchingSkills);
459  }
460 }
init(ilAssQuestionList $questionList)
setNumRequiredBookingsForSkillTriggering($numRequiredBookingsForSkillTriggering)
invokeSkillLevelTrigger($skillLevelId, $skillTrefId)
calculateReachedSkillPointsFromTestPoints($skillPoints, $maxTestPoints, $reachedTestPoints)
$result
__construct(ilDBInterface $db, $testId, $refId)
Interface ilDBInterface.
static getProfilesOfUser($a_user_id)
Get profiles of a user.
isAssignedSkill($skillBaseId, $skillTrefId)
noProfileMatchingAssignedSkillExists($availableSkillProfiles)
bookToSkillPointAccount($skillBaseId, $skillTrefId, $maxSkillPoints, $reachedSkillPoints)
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.
Create styles array
The data for the language used.
Class ilParserQuestionProvider.
initTestQuestionData(ilAssQuestionList $questionList)
doesNumBookingsExceedRequiredBookingsBarrier(ilTestSkillPointAccount $skillPointAccount)
Basic Skill.
determineReachedSkillPointsWithSolutionCompare(ilAssQuestionSolutionComparisonExpressionList $expressionList)