ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilAssMultiOptionQuestionFeedback.php
Go to the documentation of this file.
1 <?php
2 
19 require_once 'Modules/TestQuestionPool/classes/feedback/class.ilAssQuestionFeedback.php';
20 
33 {
37  public const TABLE_NAME_SPECIFIC_FEEDBACK = 'qpl_fb_specific';
38 
43  public function getSpecificAnswerFeedbackTestPresentation(int $questionId, int $questionIndex, int $answerIndex): string
44  {
45  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
46  return $this->cleanupPageContent(
47  $this->getPageObjectContent(
49  $this->getSpecificAnswerFeedbackPageObjectId($questionId, $questionIndex, $answerIndex)
50  )
51  );
52  }
54  $questionId,
55  $questionIndex,
56  $answerIndex
57  );
58  }
59 
65  {
66  if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
67  $header = new ilFormSectionHeaderGUI();
68  $header->setTitle($this->lng->txt('feedback_answers'));
69  $form->addItem($header);
70 
71  foreach ($this->getAnswerOptionsByAnswerIndex() as $index => $answer) {
72  $propertyLabel = $this->questionOBJ->prepareTextareaOutput(
73  $this->buildAnswerOptionLabel($index, $answer),
74  true
75  );
76 
77  $propertyPostVar = "feedback_answer_$index";
78 
80  $propertyLabel,
81  $propertyPostVar,
82  $this->questionOBJ->isAdditionalContentEditingModePageObject()
83  ));
84  }
85  }
86  }
87 
92  public function initSpecificFormProperties(ilPropertyFormGUI $form): void
93  {
94  if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
95  foreach ($this->getAnswerOptionsByAnswerIndex() as $index => $answer) {
96  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
97  $value = $this->getPageObjectNonEditableValueHTML(
99  $this->getSpecificAnswerFeedbackPageObjectId($this->questionOBJ->getId(), 0, $index)
100  );
101  } else {
102  $value = $this->questionOBJ->prepareTextareaOutput(
103  $this->getSpecificAnswerFeedbackContent($this->questionOBJ->getId(), 0, $index)
104  );
105  }
106 
107  $form->getItemByPostVar("feedback_answer_$index")->setValue($value);
108  }
109  }
110  }
111 
112  public function saveSpecificFormProperties(ilPropertyFormGUI $form): void
113  {
114  if (!$this->questionOBJ->isAdditionalContentEditingModePageObject()) {
115  foreach ($this->getAnswerOptionsByAnswerIndex() as $index => $answer) {
117  $this->questionOBJ->getId(),
118  0,
119  $index,
120  (string) ($form->getInput("feedback_answer_$index") ?? '')
121  );
122  }
123  }
124  }
125 
126  public function getSpecificAnswerFeedbackContent(int $questionId, int $questionIndex, int $answerIndex): string
127  {
128  require_once 'Services/RTE/classes/class.ilRTE.php';
129 
130  $res = $this->db->queryF(
131  "SELECT * FROM {$this->getSpecificFeedbackTableName()}
132  WHERE question_fi = %s AND question = %s AND answer = %s",
133  ['integer', 'integer', 'integer'],
134  [$questionId, $questionIndex, $answerIndex]
135  );
136 
137  $feedbackContent = '';
138 
139  if ($this->db->numRows($res) > 0) {
140  $row = $this->db->fetchAssoc($res);
141  $feedbackContent = ilRTE::_replaceMediaObjectImageSrc(
142  $this->questionOBJ->getHtmlQuestionContentPurifier()->purify($row['feedback'] ?? ''),
143  1
144  );
145  }
146 
147  return $feedbackContent;
148  }
149 
150  public function getAllSpecificAnswerFeedbackContents(int $questionId): string
151  {
152  require_once 'Services/RTE/classes/class.ilRTE.php';
153 
154  $res = $this->db->queryF(
155  "SELECT feedback FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
156  ['integer'],
157  [$questionId]
158  );
159 
160  $allFeedbackContents = '';
161 
162  while ($row = $this->db->fetchAssoc($res)) {
163  $allFeedbackContents .= ilRTE::_replaceMediaObjectImageSrc($row['feedback'] ?? '', 1);
164  }
165 
166  return $allFeedbackContents;
167  }
168 
169  public function saveSpecificAnswerFeedbackContent(int $questionId, int $questionIndex, int $answerIndex, string $feedbackContent): int
170  {
171  if ($feedbackContent !== '') {
172  $feedbackContent = ilRTE::_replaceMediaObjectImageSrc(
173  $this->questionOBJ->getHtmlQuestionContentPurifier()->purify($feedbackContent),
174  0
175  );
176  }
177 
178  $feedbackId = $this->getSpecificAnswerFeedbackId($questionId, $questionIndex, $answerIndex);
179 
180  if ($feedbackId !== -1) {
181  $this->db->update(
183  [
184  'feedback' => ['text', $feedbackContent],
185  'tstamp' => ['integer', time()]
186  ],
187  [
188  'feedback_id' => ['integer', $feedbackId],
189  ]
190  );
191  } else {
192  $feedbackId = $this->db->nextId($this->getSpecificFeedbackTableName());
193 
194  $this->db->insert($this->getSpecificFeedbackTableName(), [
195  'feedback_id' => ['integer', $feedbackId],
196  'question_fi' => ['integer', $questionId],
197  'question' => ['integer', $questionIndex],
198  'answer' => ['integer', $answerIndex],
199  'feedback' => ['text', $feedbackContent],
200  'tstamp' => ['integer', time()]
201  ]);
202  }
203 
204  return $feedbackId;
205  }
206 
207  public function deleteSpecificAnswerFeedbacks(int $questionId, bool $isAdditionalContentEditingModePageObject): void
208  {
209  if ($isAdditionalContentEditingModePageObject) {
210  require_once 'Modules/TestQuestionPool/classes/feedback/class.ilAssSpecificFeedbackIdentifierList.php';
211  $feedbackIdentifiers = new ilAssSpecificFeedbackIdentifierList();
212  $feedbackIdentifiers->load($questionId);
213 
214  foreach ($feedbackIdentifiers as $identifier) {
217  $identifier->getFeedbackId()
218  );
219  }
220  }
221 
222  $this->db->manipulateF(
223  "DELETE FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
224  ['integer'],
225  [$questionId]
226  );
227  }
228 
229  protected function duplicateSpecificFeedback(int $originalQuestionId, int $duplicateQuestionId): void
230  {
231  $res = $this->db->queryF(
232  "SELECT * FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
233  ['integer'],
234  [$originalQuestionId]
235  );
236 
237  while ($row = $this->db->fetchAssoc($res)) {
238  $nextId = $this->db->nextId($this->getSpecificFeedbackTableName());
239 
240  $this->db->insert($this->getSpecificFeedbackTableName(), [
241  'feedback_id' => ['integer', $nextId],
242  'question_fi' => ['integer', $duplicateQuestionId],
243  'question' => ['integer', $row['question']],
244  'answer' => ['integer', $row['answer']],
245  'feedback' => ['text', $row['feedback']],
246  'tstamp' => ['integer', time()]
247  ]);
248 
249  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
250  $pageObjectType = $this->getSpecificAnswerFeedbackPageObjectType();
251  $this->duplicatePageObject($pageObjectType, $row['feedback_id'], $nextId, $duplicateQuestionId);
252  }
253  }
254  }
255 
256  protected function syncSpecificFeedback(int $originalQuestionId, int $duplicateQuestionId): void
257  {
258  // delete specific feedback of the original
259  $this->db->manipulateF(
260  "DELETE FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
261  ['integer'],
262  [$originalQuestionId]
263  );
264 
265  // get specific feedback of the actual question
266  $res = $this->db->queryF(
267  "SELECT * FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
268  ['integer'],
269  [$duplicateQuestionId]
270  );
271 
272  // save specific feedback to the original
273  while ($row = $this->db->fetchAssoc($res)) {
274  $nextId = $this->db->nextId($this->getSpecificFeedbackTableName());
275 
276  $this->db->insert($this->getSpecificFeedbackTableName(), [
277  'feedback_id' => ['integer', $nextId],
278  'question_fi' => ['integer', $originalQuestionId],
279  'question' => ['integer', $row['question']],
280  'answer' => ['integer', $row['answer']],
281  'feedback' => ['text', $row['feedback']],
282  'tstamp' => ['integer', time()]
283  ]);
284  }
285  }
286 
287  final protected function getSpecificAnswerFeedbackId(int $questionId, int $questionIndex, int $answerIndex): int
288  {
289  $res = $this->db->queryF(
290  "SELECT feedback_id FROM {$this->getSpecificFeedbackTableName()}
291  WHERE question_fi = %s AND question = %s AND answer = %s",
292  ['integer', 'integer', 'integer'],
293  [$questionId, $questionIndex, $answerIndex]
294  );
295 
296  $row = $this->db->fetchAssoc($res);
297  return $row['feedback_id'] ?? -1;
298  }
299 
305  protected function getSpecificFeedbackContentForFeedbackIds(array $feedback_ids): array
306  {
307  $res = $this->db->query(
308  "SELECT feedback_id, feedback FROM {$this->getSpecificFeedbackTableName()} WHERE "
309  . $this->db->in('feedback_id', $feedback_ids, false, ilDBConstants::T_INTEGER)
310  );
311 
312  $content = [];
313  while ($row = $this->db->fetchAssoc($res)) {
314  $content[$row['feedback_id']] = $row['feedback'];
315  }
316  return $content;
317  }
318 
319  protected function isSpecificAnswerFeedbackId(int $feedbackId): bool
320  {
321  $row = $this->db->fetchAssoc($this->db->queryF(
322  "SELECT COUNT(feedback_id) cnt FROM {$this->getSpecificFeedbackTableName()}
323  WHERE question_fi = %s AND feedback_id = %s",
324  ['integer', 'integer'],
325  [$this->questionOBJ->getId(), $feedbackId]
326  ));
327 
328  return (bool) $row['cnt'];
329  }
330 
331  final protected function getSpecificFeedbackTableName(): string
332  {
333  return self::TABLE_NAME_SPECIFIC_FEEDBACK;
334  }
335 
336  public function getAnswerOptionsByAnswerIndex(): array
337  {
338  return $this->questionOBJ->getAnswers();
339  }
340 
341  protected function buildAnswerOptionLabel(int $index, $answer): string
342  {
343  return $answer->getAnswertext();
344  }
345 
351  final protected function getSpecificAnswerFeedbackPageObjectId(int $questionId, int $questionIndex, int $answerIndex): int
352  {
353  $pageObjectId = $this->getSpecificAnswerFeedbackId($questionId, $questionIndex, $answerIndex);
354 
355  if ($pageObjectId === -1) {
356  $pageObjectId = $this->saveSpecificAnswerFeedbackContent($questionId, $questionIndex, $answerIndex, '');
357  }
358 
359  return $pageObjectId;
360  }
361 
362  public function getSpecificAnswerFeedbackExportPresentation(int $questionId, int $questionIndex, int $answerIndex): string
363  {
364  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
365  $specificAnswerFeedbackExportPresentation = $this->getPageObjectXML(
367  $this->getSpecificAnswerFeedbackPageObjectId($questionId, $questionIndex, $answerIndex)
368  );
369  } else {
370  $specificAnswerFeedbackExportPresentation = $this->getSpecificAnswerFeedbackContent(
371  $questionId,
372  $questionIndex,
373  $answerIndex
374  );
375  }
376 
377  return $specificAnswerFeedbackExportPresentation;
378  }
379 
380  public function importSpecificAnswerFeedback(int $questionId, int $questionIndex, int $answerIndex, string $feedbackContent): void
381  {
382  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
383  $pageObjectId = $this->getSpecificAnswerFeedbackPageObjectId($questionId, $questionIndex, $answerIndex);
384  $pageObjectType = $this->getSpecificAnswerFeedbackPageObjectType();
385 
386  $this->createPageObject($pageObjectType, $pageObjectId, $feedbackContent);
387  } else {
388  $this->saveSpecificAnswerFeedbackContent($questionId, $questionIndex, $answerIndex, $feedbackContent);
389  }
390  }
391 
392  public function specificAnswerFeedbackExists(): bool
393  {
394  $res = $this->db->queryF(
395  "SELECT answer FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
396  ['integer'],
397  [$this->questionOBJ->getId()]
398  );
399 
400  $allFeedbackContents = '';
401 
402  while ($row = $this->db->fetchAssoc($res)) {
403  $allFeedbackContents .= $this->getSpecificAnswerFeedbackExportPresentation(
404  $this->questionOBJ->getId(),
405  0,
406  $row['answer']
407  );
408  }
409 
410  return (bool) strlen(trim(strip_tags($allFeedbackContents)));
411  }
412 }
static _replaceMediaObjectImageSrc(string $a_text, int $a_direction=0, string $nic='')
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
getSpecificAnswerFeedbackContent(int $questionId, int $questionIndex, int $answerIndex)
duplicatePageObject(string $pageObjectType, int $originalPageObjectId, int $duplicatePageObjectId, int $duplicatePageObjectParentId)
$res
Definition: ltiservices.php:69
importSpecificAnswerFeedback(int $questionId, int $questionIndex, int $answerIndex, string $feedbackContent)
ensurePageObjectDeleted(string $pageObjectType, int $pageObjectId)
getItemByPostVar(string $a_post_var)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPageObjectContent(string $pageObjectType, int $pageObjectId)
syncSpecificFeedback(int $originalQuestionId, int $duplicateQuestionId)
getSpecificAnswerFeedbackPageObjectId(int $questionId, int $questionIndex, int $answerIndex)
returns a useable page object id for specific answer feedback page objects for the given question id ...
getSpecificAnswerFeedbackTestPresentation(int $questionId, int $questionIndex, int $answerIndex)
returns the html of SPECIFIC feedback for the given question id and answer index for test presentatio...
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
$index
Definition: metadata.php:145
const TABLE_NAME_SPECIFIC_FEEDBACK
table name for specific feedback
createPageObject(string $pageObjectType, int $pageObjectId, string $pageObjectContent)
completeSpecificFormProperties(ilPropertyFormGUI $form)
completes a given form object with the specific form properties required by this question type ...
getSpecificAnswerFeedbackExportPresentation(int $questionId, int $questionIndex, int $answerIndex)
getPageObjectXML(string $pageObjectType, int $pageObjectId)
getSpecificAnswerFeedbackId(int $questionId, int $questionIndex, int $answerIndex)
buildFeedbackContentFormProperty(string $label, string $postVar, bool $asNonEditable)
builds and returns a form property gui object with the given label and postvar that is addable to pro...
initSpecificFormProperties(ilPropertyFormGUI $form)
initialises a given form object&#39;s specific form properties relating to this question type ...
getPageObjectNonEditableValueHTML(string $pageObjectType, int $pageObjectId)
returns html content to be used as value for non editable value form properties in feedback editing f...
duplicateSpecificFeedback(int $originalQuestionId, int $duplicateQuestionId)
deleteSpecificAnswerFeedbacks(int $questionId, bool $isAdditionalContentEditingModePageObject)
saveSpecificAnswerFeedbackContent(int $questionId, int $questionIndex, int $answerIndex, string $feedbackContent)