122 $this->questionInstanceTypeFilter = (string) $questionInstanceTypeFilter;
132 $this->includeQuestionIdsFilter = $questionIdsFilter;
162 $this->fieldFilters[$fieldName] = $fieldValue;
167 $this->taxFilters[$taxId] = $taxNodes;
174 $this->taxFiltersExcludeAnyObjectsWithTaxonomies = $flag;
214 $this->join_obj_data = $a_val;
246 return 'qpl_questions.obj_fi = ' . $this->db->quote($this->
getParentObjId(),
'integer');
260 foreach ($this->fieldFilters as $fieldName => $fieldValue) {
261 switch ($fieldName) {
267 $expressions[] = $this->db->like(
'qpl_questions.' . $fieldName,
'text',
"%%$fieldValue%%");
272 $expressions[] =
"qpl_qst_type.type_tag = {$this->db->quote($fieldValue, 'text')}";
276 if ($fieldValue !=
"" && !is_array($fieldValue)) {
277 $fieldValue = array($fieldValue);
279 $expressions[] = $this->db->in(
"qpl_questions.question_id", $fieldValue,
false,
"integer");
283 if ($this->join_obj_data) {
284 $expressions[] = $this->db->like(
'object_data.title',
'text',
"%%$fieldValue%%");
296 if ($this->taxFiltersExcludeAnyObjectsWithTaxonomies) {
297 $expressions[] =
'question_id NOT IN (SELECT DISTINCT item_id FROM tax_node_assignment)';
301 foreach ($this->taxFilters as $taxId => $taxNodes) {
306 foreach ($taxNodes as $taxNode) {
307 $forceBypass =
false;
310 $this->taxParentTypes[$taxId],
311 $this->taxParentIds[$taxId],
317 $this->parentObjType,
323 $taxItems = array_merge($taxItemsByTaxParent, $taxItemsByParent);
324 foreach ($taxItems as $taxItem) {
325 $questionIds[$taxItem[
'item_id']] = $taxItem[
'item_id'];
330 $expressions[] = $this->db->in(
'question_id', $questionIds,
false,
'integer');
344 protected function getTaxItems($parentType, $parentObjId, $taxId, $taxNode): array
355 $subNodes = $taxTree->getSubTreeIds($taxNode);
356 $subNodes[] = $taxNode;
358 return $taxNodeAssignment->getAssignmentsOfNode($subNodes);
364 case self::QUESTION_INSTANCE_TYPE_ORIGINALS:
365 return 'qpl_questions.original_id IS NULL';
366 case self::QUESTION_INSTANCE_TYPE_DUPLICATES:
367 return 'qpl_questions.original_id IS NOT NULL';
368 case self::QUESTION_INSTANCE_TYPE_ALL:
381 $expressions[] = $this->db->in(
382 'qpl_questions.question_id',
391 'qpl_questions.question_id',
397 if ($IN ==
' 1=2 ') {
401 $expressions[] = $IN;
409 if ($this->parentObjId) {
410 return "qpl_questions.obj_fi = {$this->db->quote($this->parentObjId, 'integer')}";
421 case self::ANSWER_STATUS_FILTER_ALL_NON_CORRECT:
424 (tst_test_result.question_fi IS NULL OR tst_test_result.points < qpl_questions.points) 428 case self::ANSWER_STATUS_FILTER_NON_ANSWERED_ONLY:
430 $expressions[] =
'tst_test_result.question_fi IS NULL';
433 case self::ANSWER_STATUS_FILTER_WRONG_ANSWERED_ONLY:
435 $expressions[] =
'tst_test_result.question_fi IS NOT NULL';
436 $expressions[] =
'tst_test_result.points < qpl_questions.points';
446 INNER JOIN qpl_qst_type 447 ON qpl_qst_type.question_type_id = qpl_questions.question_type_fi 450 if ($this->join_obj_data) {
452 INNER JOIN object_data 453 ON object_data.obj_id = qpl_questions.obj_fi 460 INNER JOIN tst_test_question tstquest 461 ON tstquest.question_fi = qpl_questions.question_id 467 LEFT JOIN tst_test_result 468 ON tst_test_result.question_fi = qpl_questions.question_id 469 AND tst_test_result.active_fi = {$this->db->quote($this->getAnswerStatusActiveId(), 'integer')} 492 $CONDITIONS = array_merge(
500 $CONDITIONS = implode(
' AND ', $CONDITIONS);
502 return strlen($CONDITIONS) ?
'AND ' . $CONDITIONS :
'';
507 $selectFields = array(
509 'qpl_qst_type.type_tag',
510 'qpl_qst_type.plugin',
511 'qpl_qst_type.plugin_name',
512 'qpl_questions.points max_points' 515 if ($this->join_obj_data) {
516 $selectFields[] =
'object_data.title parent_title';
520 $selectFields[] =
'tst_test_result.points reached_points';
521 $selectFields[] =
"CASE 522 WHEN tst_test_result.points IS NULL THEN '" . self::QUESTION_ANSWER_STATUS_NON_ANSWERED .
"' 523 WHEN tst_test_result.points < qpl_questions.points THEN '" . self::QUESTION_ANSWER_STATUS_WRONG_ANSWERED .
"' 524 ELSE '" . self::QUESTION_ANSWER_STATUS_CORRECT_ANSWERED .
"' 525 END question_answer_status 529 $selectFields = implode(
",\n\t\t\t\t", $selectFields);
532 SELECT {$selectFields} 539 {$this->getSelectFieldsExpression()} 543 {$this->getTableJoinExpression()} 545 WHERE qpl_questions.tstamp > 0 552 {$this->getConditionalFilterExpression()} 557 UNION {$this->buildBasicQuery()} 558 AND {$this->db->in('qpl_questions.question_id', $this->getForcedQuestionIds(), false, 'integer')} 569 $tags_trafo = $this->
refinery->string()->stripTags();
572 $res = $this->db->query($query);
573 while ($row = $this->db->fetchAssoc(
$res)) {
580 $row[
'title'] = $tags_trafo->transform($row[
'title'] ??
' ');
581 $row[
'description'] = $tags_trafo->transform($row[
'description'] !==
'' && $row[
'description'] !== null ? $row[
'description'] :
' ');
582 $row[
'author'] = $tags_trafo->transform($row[
'author']);
584 $row[
'ttype'] = $this->
lng->txt($row[
'type_tag']);
585 $row[
'feedback'] = $this->
hasFeedback((
int) $row[
'question_id']);
586 $row[
'hints'] = $this->
hasHints((
int) $row[
'question_id']);
590 $this->filter_comments === self::QUESTION_COMMENTED_ONLY && $row[
'comments'] === 0
591 || $this->filter_comments === self::QUESTION_COMMENTED_EXCLUDED && $row[
'comments'] > 0
596 $this->questions[ $row[
'question_id'] ] = $row;
602 if ($this->notes_service === null) {
605 $notes_context = $this->notes_service->data()->context(
610 return $this->notes_service->domain()->getNrOfCommentsForContext($notes_context);
615 $this->filter_comments = $commented;
624 $res = $this->db->queryF(
625 "SELECT feedback, feedback_id FROM qpl_fb_generic 626 WHERE question_fi = %s 628 SELECT feedback, feedback_id FROM qpl_fb_specific 629 WHERE question_fi = %s",
630 [
'integer',
'integer', ],
631 [$question_id, $question_id]
633 while ($row = $this->db->fetchAssoc(
$res)) {
634 if (trim((
string) $row[
'feedback']) !==
'') {
637 foreach ($pagetypes as $pagetype) {
646 protected function hasHints(
int $question_id): bool
649 return iterator_count($questionHintList) > 0;
654 $taxAssignmentData = [];
661 $assignments = $taxAssignment->getAssignmentsOfItem($questionId);
663 foreach ($assignments as $assData) {
664 if (!isset($taxAssignmentData[ $assData[
'tax_id'] ])) {
665 $taxAssignmentData[ $assData[
'tax_id'] ] = [];
668 $nodeData = $taxTree->getNodeData($assData[
'node_id']);
670 $assData[
'node_lft'] = $nodeData[
'lft'];
672 $taxAssignmentData[ $assData[
'tax_id'] ][ $assData[
'node_id'] ] = $assData;
676 return $taxAssignmentData;
681 if (!isset($questionData[
'plugin'])) {
685 if (!$questionData[
'plugin']) {
689 if (!$this->component_repository->getComponentByTypeAndName(
692 )->getPluginSlotById(
'qst')->hasPluginName((
string) $questionData[
'plugin_name'])) {
696 return $this->component_repository
697 ->getComponentByTypeAndName(
705 (
string) $questionData[
'plugin_name']
711 return $this->questions[$questionId];
721 return isset($this->questions[$questionId]);
733 public function getTitle(
string $a_comp_id,
string $a_item_type,
int $a_item_id): string
735 if ($a_comp_id !=
'qpl' || $a_item_type !=
'quest' || !$a_item_id) {
739 if (!isset($this->questions[$a_item_id])) {
743 return $this->questions[$a_item_id][
'title'];
750 'No active id given! You cannot use the answer status filter without giving an active id.'
getExcludeQuestionIdsFilter()
static getListByQuestionId($questionId)
instantiates a question hint list for the passed question id
Readable part of repository interface to ilComponentDataDB.
setAnswerStatusFilter($answerStatusFilter)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$includeQuestionIdsFilter
isActiveQuestionType(array $questionData)
static completeMissingPluginName($question_type_data)
getAnswerStatusActiveId()
getSelectFieldsExpression()
int $answerStatusActiveId
getTaxItems($parentType, $parentObjId, $taxId, $taxNode)
getQuestionIdsFilterExpressions()
getIncludeQuestionIdsFilter()
getParentObjFilterExpression()
setExcludeQuestionIdsFilter($excludeQuestionIdsFilter)
const QUESTION_COMMENTED_ONLY
const QUESTION_COMMENTED_EXCLUDED
string $questionCompletionStatusFilter
hasFeedback(int $question_id)
const QUESTION_INSTANCE_TYPE_DUPLICATES
array $availableTaxonomyIds
getTitle(string $a_comp_id, string $a_item_type, int $a_item_id)
Get title of an assigned item.
getDataArrayForQuestionId($questionId)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getConditionalFilterExpression()
addTaxonomyFilterNoTaxonomySet(bool $flag)
bool $taxFiltersExcludeAnyObjectsWithTaxonomies
__construct(private ilDBInterface $db, private ilLanguage $lng, private Refinery $refinery, private ilComponentRepository $component_repository, private ?NotesService $notes_service=null)
setAnswerStatusActiveId($answerStatusActiveId)
const ANSWER_STATUS_FILTER_NON_ANSWERED_ONLY
setCommentFilter(int $commented=null)
static _existsAndNotEmpty(string $a_parent_type, int $a_id, string $a_lang="-")
checks whether page exists and is not empty (may return true on some empty pages) ...
getAvailableTaxonomyIds()
getTaxonomyFilterExpressions()
setIncludeQuestionIdsFilter($questionIdsFilter)
getAnswerStatusFilterExpressions()
setParentObjId($parentObjId)
setParentObjectType($parentObjType)
string $questionInstanceTypeFilter
$excludeQuestionIdsFilter
getParentObjectIdFilterExpression()
const PAGE_OBJECT_TYPE_GENERIC_FEEDBACK
type for generic feedback page objects
getFieldFilterExpressions()
addTaxonomyFilter($taxId, $taxNodes, $parentObjId, $parentObjType)
getQuestionInstanceTypeFilter()
getJoinObjectData()
Get if object data table should be joined.
getNumberOfCommentsForQuestion(int $question_id)
const ANSWER_STATUS_FILTER_WRONG_ANSWERED_ONLY
hasHints(int $question_id)
getQuestionInstanceTypeFilterExpression()
const QUESTION_COMPLETION_STATUS_COMPLETE
setQuestionInstanceTypeFilter($questionInstanceTypeFilter)
const ANSWER_STATUS_FILTER_ALL_NON_CORRECT
answer status filter value domain
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setForcedQuestionIds($forcedQuestionIds)
array $parentObjIdsFilter
const QUESTION_ANSWER_STATUS_CORRECT_ANSWERED
const QUESTION_COMPLETION_STATUS_BOTH
const QUESTION_ANSWER_STATUS_WRONG_ANSWERED
setJoinObjectData($a_val)
Set if object data table should be joined.
const QUESTION_COMPLETION_STATUS_INCOMPLETE
addFieldFilter($fieldName, $fieldValue)
setParentObjIdsFilter($parentObjIdsFilter)
const QUESTION_INSTANCE_TYPE_ALL
loadTaxonomyAssignmentData($parentObjId, $questionId)
const QUESTION_INSTANCE_TYPE_ORIGINALS
const QUESTION_ANSWER_STATUS_NON_ANSWERED
answer status domain for single questions
const PAGE_OBJECT_TYPE_SPECIFIC_FEEDBACK
type for specific feedback page objects
setQuestionCompletionStatusFilter($questionCompletionStatusFilter)
getQuestionCompletionStatusFilter()
setAvailableTaxonomyIds($availableTaxonomyIds)
Refinery Factory $refinery