ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilAssMultiOptionQuestionFeedback.php
Go to the documentation of this file.
1 <?php
2 
31 {
35  public const TABLE_NAME_SPECIFIC_FEEDBACK = 'qpl_fb_specific';
36 
41  public function getSpecificAnswerFeedbackTestPresentation(int $question_id, int $question_index, int $answer_index): string
42  {
43  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
44  return $this->cleanupPageContent(
45  $this->getPageObjectContent(
47  $this->getSpecificAnswerFeedbackPageObjectId($question_id, $question_index, $answer_index)
48  )
49  );
50  }
51 
53  $question_id,
54  $question_index,
55  $answer_index
56  );
57  }
58 
64  {
65  if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
66  $header = new ilFormSectionHeaderGUI();
67  $header->setTitle($this->lng->txt('feedback_answers'));
68  $form->addItem($header);
69 
70  foreach ($this->getAnswerOptionsByAnswerIndex() as $index => $answer) {
72  $this->buildAnswerOptionLabel($index, $answer),
73  true
74  );
75 
76  $propertyPostVar = "feedback_answer_$index";
77 
79  $propertyLabel,
80  $propertyPostVar,
81  $this->questionOBJ->isAdditionalContentEditingModePageObject()
82  ));
83  }
84  }
85  }
86 
91  public function initSpecificFormProperties(ilPropertyFormGUI $form): void
92  {
93  if (!$this->questionOBJ->getSelfAssessmentEditingMode()) {
94  foreach ($this->getAnswerOptionsByAnswerIndex() as $index => $answer) {
95  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
96  $value = $this->getPageObjectNonEditableValueHTML(
98  $this->getSpecificAnswerFeedbackPageObjectId($this->questionOBJ->getId(), 0, $index)
99  );
100  } else {
102  $this->getSpecificAnswerFeedbackContent($this->questionOBJ->getId(), 0, $index)
103  );
104  }
105 
106  $form->getItemByPostVar("feedback_answer_$index")->setValue($value);
107  }
108  }
109  }
110 
111  public function saveSpecificFormProperties(ilPropertyFormGUI $form): void
112  {
113  if (!$this->questionOBJ->isAdditionalContentEditingModePageObject()) {
114  foreach ($this->getAnswerOptionsByAnswerIndex() as $index => $answer) {
116  $this->questionOBJ->getId(),
117  0,
118  $index,
119  (string) ($form->getInput("feedback_answer_$index") ?? '')
120  );
121  }
122  }
123  }
124 
125  public function getSpecificAnswerFeedbackContent(int $question_id, int $question_index, int $answer_index): string
126  {
127  $res = $this->db->queryF(
128  "SELECT * FROM {$this->getSpecificFeedbackTableName()}
129  WHERE question_fi = %s AND question = %s AND answer = %s",
130  ['integer', 'integer', 'integer'],
131  [$question_id, $question_index, $answer_index]
132  );
133 
134  $feedback_content = '';
135 
136  if ($this->db->numRows($res) > 0) {
137  $row = $this->db->fetchAssoc($res);
138  $feedback_content = ilRTE::_replaceMediaObjectImageSrc(
139  $this->questionOBJ->getHtmlQuestionContentPurifier()->purify($row['feedback'] ?? ''),
140  1
141  );
142  }
143 
144  return $feedback_content;
145  }
146 
147  public function getAllSpecificAnswerFeedbackContents(int $question_id): string
148  {
149  $res = $this->db->queryF(
150  "SELECT feedback FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
151  ['integer'],
152  [$question_id]
153  );
154 
155  $allFeedbackContents = '';
156 
157  while ($row = $this->db->fetchAssoc($res)) {
158  $allFeedbackContents .= ilRTE::_replaceMediaObjectImageSrc($row['feedback'] ?? '', 1);
159  }
160 
161  return $allFeedbackContents;
162  }
163 
164  public function getAllSpecificAnswerPageEditorFeedbackContents(int $question_id): string
165  {
166  $feedback_identifiers = new ilAssSpecificFeedbackIdentifierList();
167  $feedback_identifiers->load($question_id);
168 
169  $all_feedback_content = '';
170  foreach ($feedback_identifiers as $identifier) {
171  $feedback_content = $this->getPageObjectContent(
173  $identifier->getFeedbackId()
174  );
175  $all_feedback_content .= $this->cleanupPageContent($feedback_content);
176  }
177 
178  return $all_feedback_content;
179  }
180 
181  public function saveSpecificAnswerFeedbackContent(int $question_id, int $question_index, int $answer_index, string $feedback_content): int
182  {
183  if ($feedback_content !== '') {
184  $feedback_content = ilRTE::_replaceMediaObjectImageSrc(
185  $this->questionOBJ->getHtmlQuestionContentPurifier()->purify($feedback_content),
186  0
187  );
188  }
189 
190  $feedback_id = $this->getSpecificAnswerFeedbackId($question_id, $question_index, $answer_index);
191 
192  if ($feedback_id !== -1) {
193  $this->db->update(
195  [
196  'feedback' => ['text', $feedback_content],
197  'tstamp' => ['integer', time()]
198  ],
199  [
200  'feedback_id' => ['integer', $feedback_id],
201  ]
202  );
203  } else {
204  $feedback_id = $this->db->nextId($this->getSpecificFeedbackTableName());
205 
206  $this->db->insert($this->getSpecificFeedbackTableName(), [
207  'feedback_id' => ['integer', $feedback_id],
208  'question_fi' => ['integer', $question_id],
209  'question' => ['integer', $question_index],
210  'answer' => ['integer', $answer_index],
211  'feedback' => ['text', $feedback_content],
212  'tstamp' => ['integer', time()]
213  ]);
214  }
215 
216  return $feedback_id;
217  }
218 
219  public function deleteSpecificAnswerFeedbacks(int $question_id, bool $is_additional_content_editing_mode_page_object): void
220  {
221  if ($is_additional_content_editing_mode_page_object) {
222  $feedback_identifiers = new ilAssSpecificFeedbackIdentifierList();
223  $feedback_identifiers->load($question_id);
224 
225  foreach ($feedback_identifiers as $identifier) {
228  $identifier->getFeedbackId()
229  );
230  }
231  }
232 
233  $this->db->manipulateF(
234  "DELETE FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
235  ['integer'],
236  [$question_id]
237  );
238  }
239 
240  protected function duplicateSpecificFeedback(int $original_question_id, int $duplicate_question_id): void
241  {
242  $res = $this->db->queryF(
243  "SELECT * FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
244  ['integer'],
245  [$original_question_id]
246  );
247 
248  while ($row = $this->db->fetchAssoc($res)) {
249  $next_id = $this->db->nextId($this->getSpecificFeedbackTableName());
250 
251  $this->db->insert($this->getSpecificFeedbackTableName(), [
252  'feedback_id' => ['integer', $next_id],
253  'question_fi' => ['integer', $duplicate_question_id],
254  'question' => ['integer', $row['question']],
255  'answer' => ['integer', $row['answer']],
256  'feedback' => ['text', $row['feedback']],
257  'tstamp' => ['integer', time()]
258  ]);
259 
260  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
261  $pageObjectType = $this->getSpecificAnswerFeedbackPageObjectType();
262  $this->duplicatePageObject($pageObjectType, $row['feedback_id'], $next_id, $duplicate_question_id);
263  }
264  }
265  }
266 
267  protected function syncSpecificFeedback(int $original_question_id, int $duplicate_question_id): void
268  {
269  // delete specific feedback of the original
270  $this->db->manipulateF(
271  "DELETE FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
272  ['integer'],
273  [$original_question_id]
274  );
275 
276  // get specific feedback of the actual question
277  $res = $this->db->queryF(
278  "SELECT * FROM {$this->getSpecificFeedbackTableName()} WHERE question_fi = %s",
279  ['integer'],
280  [$duplicate_question_id]
281  );
282 
283  // save specific feedback to the original
284  while ($row = $this->db->fetchAssoc($res)) {
285  $next_id = $this->db->nextId($this->getSpecificFeedbackTableName());
286 
287  $this->db->insert($this->getSpecificFeedbackTableName(), [
288  'feedback_id' => ['integer', $next_id],
289  'question_fi' => ['integer', $original_question_id],
290  'question' => ['integer', $row['question']],
291  'answer' => ['integer', $row['answer']],
292  'feedback' => ['text', $row['feedback']],
293  'tstamp' => ['integer', time()]
294  ]);
295  }
296  }
297 
298  final protected function getSpecificAnswerFeedbackId(int $question_id, int $question_index, int $answer_index): int
299  {
300  $res = $this->db->queryF(
301  "SELECT feedback_id FROM {$this->getSpecificFeedbackTableName()}
302  WHERE question_fi = %s AND question = %s AND answer = %s",
303  ['integer', 'integer', 'integer'],
304  [$question_id, $question_index, $answer_index]
305  );
306 
307  $row = $this->db->fetchAssoc($res);
308  return $row['feedback_id'] ?? -1;
309  }
310 
316  protected function getSpecificFeedbackContentForFeedbackIds(array $feedback_ids): array
317  {
318  $res = $this->db->query(
319  "SELECT feedback_id, feedback FROM {$this->getSpecificFeedbackTableName()} WHERE "
320  . $this->db->in('feedback_id', $feedback_ids, false, ilDBConstants::T_INTEGER)
321  );
322 
323  $content = [];
324  while ($row = $this->db->fetchAssoc($res)) {
325  $content[$row['feedback_id']] = $row['feedback'];
326  }
327  return $content;
328  }
329 
330  protected function isSpecificAnswerFeedbackId(int $feedback_id): bool
331  {
332  $row = $this->db->fetchAssoc($this->db->queryF(
333  "SELECT COUNT(feedback_id) cnt FROM {$this->getSpecificFeedbackTableName()}
334  WHERE question_fi = %s AND feedback_id = %s",
335  ['integer', 'integer'],
336  [$this->questionOBJ->getId(), $feedback_id]
337  ));
338 
339  return (bool) $row['cnt'];
340  }
341 
342  final protected function getSpecificFeedbackTableName(): string
343  {
344  return self::TABLE_NAME_SPECIFIC_FEEDBACK;
345  }
346 
347  public function getAnswerOptionsByAnswerIndex(): array
348  {
349  return $this->questionOBJ->getAnswers();
350  }
351 
352  protected function buildAnswerOptionLabel(int $index, $answer): string
353  {
354  return $answer->getAnswertext();
355  }
356 
362  final protected function getSpecificAnswerFeedbackPageObjectId(int $question_id, int $question_index, int $answer_index): int
363  {
364  $page_object_id = $this->getSpecificAnswerFeedbackId($question_id, $question_index, $answer_index);
365 
366  if ($page_object_id === -1) {
367  $page_object_id = $this->saveSpecificAnswerFeedbackContent($question_id, $question_index, $answer_index, '');
368  }
369 
370  return $page_object_id;
371  }
372 
373  public function getSpecificAnswerFeedbackExportPresentation(int $question_id, int $question_index, int $answer_index): string
374  {
375  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
376  return $this->getPageObjectXML(
378  $this->getSpecificAnswerFeedbackPageObjectId($question_id, $question_index, $answer_index)
379  );
380  }
381 
382  return $this->getSpecificAnswerFeedbackContent(
383  $question_id,
384  $question_index,
385  $answer_index
386  );
387  }
388 
389  public function importSpecificAnswerFeedback(int $question_id, int $question_index, int $answer_index, string $feedback_content): void
390  {
391  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
392  $page_object_id = $this->getSpecificAnswerFeedbackPageObjectId($question_id, $question_index, $answer_index);
393  $pageObjectType = $this->getSpecificAnswerFeedbackPageObjectType();
394 
395  $this->createPageObject($pageObjectType, $page_object_id, $feedback_content);
396  } else {
397  $this->saveSpecificAnswerFeedbackContent($question_id, $question_index, $answer_index, $feedback_content);
398  }
399  }
400 
401  public function specificAnswerFeedbackExists(): bool
402  {
403  if ($this->questionOBJ->isAdditionalContentEditingModePageObject()) {
404  $all_feedback_content = $this->getAllSpecificAnswerPageEditorFeedbackContents($this->questionOBJ->getId());
405  } else {
406  $all_feedback_content = $this->getAllSpecificAnswerFeedbackContents($this->questionOBJ->getId());
407  }
408 
409  return $all_feedback_content !== '';
410  }
411 }
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...
$res
Definition: ltiservices.php:69
getSpecificAnswerFeedbackPageObjectId(int $question_id, int $question_index, int $answer_index)
returns a useable page object id for specific answer feedback page objects for the given question id ...
duplicateSpecificFeedback(int $original_question_id, int $duplicate_question_id)
getItemByPostVar(string $a_post_var)
deleteSpecificAnswerFeedbacks(int $question_id, bool $is_additional_content_editing_mode_page_object)
importSpecificAnswerFeedback(int $question_id, int $question_index, int $answer_index, string $feedback_content)
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-...
const TABLE_NAME_SPECIFIC_FEEDBACK
table name for specific feedback
getPageObjectXML(string $page_object_type, int $page_object_id)
completeSpecificFormProperties(ilPropertyFormGUI $form)
completes a given form object with the specific form properties required by this question type ...
createPageObject(string $page_object_type, int $page_object_id, string $page_object_content)
getSpecificAnswerFeedbackId(int $question_id, int $question_index, int $answer_index)
initSpecificFormProperties(ilPropertyFormGUI $form)
initialises a given form object&#39;s specific form properties relating to this question type ...
getSpecificAnswerFeedbackTestPresentation(int $question_id, int $question_index, int $answer_index)
returns the html of SPECIFIC feedback for the given question id and answer index for test presentatio...
duplicatePageObject(string $page_object_type, int $original_page_object_id, int $duplicate_page_object_id, int $duplicate_page_object_parent_id)
getSpecificAnswerFeedbackContent(int $question_id, int $question_index, int $answer_index)
getPageObjectNonEditableValueHTML(string $page_object_type, int $page_object_id)
returns html content to be used as value for non editable value form properties in feedback editing f...
syncSpecificFeedback(int $original_question_id, int $duplicate_question_id)
ensurePageObjectDeleted(string $page_object_type, int $page_object_id)
buildFeedbackContentFormProperty(string $label, string $post_var, bool $as_non_editable)
builds and returns a form property gui object with the given label and postvar that is addable to pro...
static prepareTextareaOutput(string $txt_output, bool $prepare_for_latex_output=false, bool $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free...
saveSpecificAnswerFeedbackContent(int $question_id, int $question_index, int $answer_index, string $feedback_content)
getSpecificAnswerFeedbackExportPresentation(int $question_id, int $question_index, int $answer_index)