ILIAS  release_8 Revision v8.24
class.assClozeGap.php
Go to the documentation of this file.
1<?php
20
21include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
22
36{
37 public const TYPE_TEXT = 0;
38 public const TYPE_SELECT = 1;
39 public const TYPE_NUMERIC = 2;
40 private ?Transformation $shuffler = null;
41
42 public int $type;
43
51 public $items;
52
58 public $shuffle;
59
60 private $gap_size = 0;
61
68 public function __construct($a_type)
69 {
70 $this->type = (int) $a_type;
71 $this->items = [];
72 $this->shuffle = true;
73 }
74
78 public function getType(): int
79 {
80 return $this->type;
81 }
82
83 public function isTextGap(): bool
84 {
85 return $this->type === self::TYPE_TEXT;
86 }
87
88 public function isSelectGap(): bool
89 {
90 return $this->type === self::TYPE_SELECT;
91 }
92
93 public function isNumericGap(): bool
94 {
95 return $this->type === self::TYPE_NUMERIC;
96 }
97
105 public function setType($a_type = 0): void
106 {
107 $this->type = $a_type;
108 }
109
116 public function getItems(Transformation $shuffler, ?int $gap_index = null): array
117 {
118 if (!$this->getShuffle()) {
119 return $this->items;
120 }
121
122 if ($gap_index === null) {
123 return $shuffler->transform($this->items);
124 }
125
127 for ($i = -2; $i < $gap_index; $i++) {
129 }
130
131 return $items;
132 }
133
143 public function getItemsRaw(): array
144 {
145 return $this->items;
146 }
147
157 public function getItemCount(): int
158 {
159 return count($this->items);
160 }
161
171 public function addItem($a_item): void
172 {
173 $order = $a_item->getOrder();
174 if (array_key_exists($order, $this->items)) {
175 $newitems = [];
176 for ($i = 0; $i < $order; $i++) {
177 array_push($newitems, $this->items[$i]);
178 }
179 array_push($newitems, $a_item);
180 for ($i = $order, $iMax = count($this->items); $i < $iMax; $i++) {
181 array_push($newitems, $this->items[$i]);
182 }
183 $i = 0;
184 foreach ($newitems as $idx => $item) {
185 $newitems[$idx]->setOrder($i);
186 $i++;
187 }
188 $this->items = $newitems;
189 } else {
190 array_push($this->items, $a_item);
191 }
192 }
193
204 public function setItemPoints($order, $points): void
205 {
206 foreach ($this->items as $key => $item) {
207 if ($item->getOrder() == $order) {
208 $item->setPoints($points);
209 }
210 }
211 }
212
222 public function deleteItem($order): void
223 {
224 if (array_key_exists($order, $this->items)) {
225 unset($this->items[$order]);
226 $order = 0;
227 foreach ($this->items as $key => $item) {
228 $this->items[$key]->setOrder($order);
229 $order++;
230 }
231 }
232 }
233
244 public function setItemLowerBound($order, $bound): void
245 {
246 foreach ($this->items as $key => $item) {
247 if ($item->getOrder() == $order) {
248 $item->setLowerBound($bound);
249 }
250 }
251 }
252
263 public function setItemUpperBound($order, $bound): void
264 {
265 foreach ($this->items as $key => $item) {
266 if ($item->getOrder() == $order) {
267 $item->setUpperBound($bound);
268 }
269 }
270 }
271
282 public function getItem($a_index): ?assAnswerCloze
283 {
284 if (array_key_exists($a_index, $this->items)) {
285 return $this->items[$a_index];
286 } else {
287 return null;
288 }
289 }
290
299 public function clearItems(): void
300 {
301 $this->items = [];
302 }
303
311 public function setShuffle($a_shuffle = true): void
312 {
313 $this->shuffle = (bool) $a_shuffle;
314 }
315
321 public function getShuffle(): bool
322 {
323 return $this->shuffle;
324 }
325
334 public function getMaxWidth(): int
335 {
336 $maxwidth = 0;
337 foreach ($this->items as $item) {
338 if (strlen($item->getAnswertext()) > $maxwidth) {
339 $maxwidth = strlen($item->getAnswertext());
340 }
341 }
342 return $maxwidth;
343 }
344
353 public function getBestSolutionIndexes(): array
354 {
355 $maxpoints = 0;
356 foreach ($this->items as $key => $item) {
357 if ($item->getPoints() > $maxpoints) {
358 $maxpoints = $item->getPoints();
359 }
360 }
361 $keys = [];
362 foreach ($this->items as $key => $item) {
363 if ($item->getPoints() == $maxpoints) {
364 array_push($keys, $key);
365 }
366 }
367 return $keys;
368 }
369
375 public function getBestSolutionOutput(Transformation $shuffler, $combinations = null): string
376 {
377 global $DIC;
378 $lng = $DIC['lng'];
379 switch ($this->getType()) {
380 case CLOZE_TEXT:
381 case CLOZE_SELECT:
382 $best_solutions = [];
383 if ($combinations !== null && $combinations['best_solution'] == 1) {
384 $best_solutions[$combinations['points']] = [];
385 array_push($best_solutions[$combinations['points']], $combinations['answer']);
386 } else {
387 foreach ($this->getItems($shuffler) as $answer) {
388 $points_string_for_key = (string) $answer->getPoints();
389 if (isset($best_solutions[$points_string_for_key]) && is_array($best_solutions[$points_string_for_key])) {
390 array_push($best_solutions[$points_string_for_key], $answer->getAnswertext());
391 } else {
392 $best_solutions[$points_string_for_key] = [];
393 array_push($best_solutions[$points_string_for_key], $answer->getAnswertext());
394 }
395 }
396 }
397
398 krsort($best_solutions, SORT_NUMERIC);
399 reset($best_solutions);
400 $found = current($best_solutions);
401 return join(" " . $lng->txt("or") . " ", $found);
402 break;
403 case CLOZE_NUMERIC:
404 $maxpoints = 0;
405 $foundvalue = "";
406 foreach ($this->getItems($shuffler) as $answer) {
407 if ($answer->getPoints() >= $maxpoints) {
408 $maxpoints = $answer->getPoints();
409 $foundvalue = $answer->getAnswertext();
410 }
411 }
412 return $foundvalue;
413 break;
414 default:
415 return "";
416 }
417 }
418
419 public function setGapSize(int $gap_size): void
420 {
421 $this->gap_size = $gap_size;
422 }
423
427 public function getGapSize(): int
428 {
429 return (int)$this->gap_size;
430 }
431
432 public function numericRangeExists(): bool
433 {
434 if ($this->getType() != CLOZE_NUMERIC) {
435 return false;
436 }
437
438 require_once 'Services/Math/classes/class.EvalMath.php';
439 $math = new EvalMath();
440
441 $item = $this->getItem(0);
442 $lowerBound = $math->evaluate($item->getLowerBound());
443 $upperBound = $math->evaluate($item->getUpperBound());
444 $preciseValue = $math->evaluate($item->getAnswertext());
445
446 if ($lowerBound < $preciseValue || $upperBound > $preciseValue) {
447 return true;
448 }
449
450 return false;
451 }
452}
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class for cloze question gaps.
getBestSolutionOutput(Transformation $shuffler, $combinations=null)
setItemLowerBound($order, $bound)
Sets the lower bound for a given item.
deleteItem($order)
Deletes an item at a given index.
getBestSolutionIndexes()
Returns the indexes of the best solutions for the gap.
getItemCount()
Gets the item count.
setItemPoints($order, $points)
Sets the points for a given item.
getShuffle()
Gets the shuffle state of the items.
clearItems()
Removes all gap items.
getMaxWidth()
Returns the maximum width of the gap.
setShuffle($a_shuffle=true)
Sets the shuffle state of the items.
Transformation $shuffler
setGapSize(int $gap_size)
getItem($a_index)
Gets the item with a given index.
__construct($a_type)
assClozeGap constructor
getItemsRaw()
Gets the items of a cloze gap.
addItem($a_item)
Adds a gap item.
setItemUpperBound($order, $bound)
Sets the upper bound for a given item.
getItems(Transformation $shuffler, ?int $gap_index=null)
Gets the items of a cloze gap.
setType($a_type=0)
Sets the cloze gap type.
global $DIC
Definition: feed.php:28
const CLOZE_NUMERIC
const CLOZE_SELECT
const CLOZE_TEXT
Cloze question constants.
A transformation is a function from one datatype to another.
transform($from)
Perform the transformation.
$i
Definition: metadata.php:41
$keys
Definition: metadata.php:204
string $key
Consumer key/client ID value.
Definition: System.php:193
$lng