ILIAS  trunk Revision v12.0_alpha-377-g3641b37b9db
class.ilAdvancedSearch.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
34{
35 private string $mode = '';
36 protected array $options = [];
37
38
39
40 public function setMode(string $a_mode): void
41 {
42 $this->mode = $a_mode;
43 }
44 public function getMode(): string
45 {
46 return $this->mode;
47 }
48
49 public function setOptions(array &$options): void
50 {
51 $this->options = &$options;
52 }
53
54
55 public function performSearch(): ?ilSearchResult
56 {
57 switch ($this->getMode()) {
58 case 'requirement':
59 return $this->__searchRequirement();
60
61 case 'educational':
62 return $this->__searchEducational();
63
64 case 'typical_age_range':
65 return $this->__searchTypicalAgeRange();
66
67 case 'rights':
68 return $this->__searchRights();
69
70 case 'classification':
71 return $this->__searchClassification();
72
73 case 'taxon':
74 return $this->__searchTaxon();
75
76 case 'keyword':
77 return $this->__searchKeyword();
78
79 case 'format':
80 return $this->__searchFormat();
81
82 case 'lifecycle':
83 return $this->__searchLifecycle();
84
85 case 'contribute':
86 return $this->__searchContribute();
87
88 case 'entity':
89 return $this->__searchEntity();
90
91 case 'general':
92 return $this->__searchGeneral();
93
94 case 'keyword_all':
95 return $this->__searchKeyword(false);
96
97 case 'title_description':
98 return $this->__searchTitleDescription();
99
100 case 'title':
101 return $this->__searchTitle();
102
103 case 'description':
104 return $this->__searchDescription();
105
106 case 'language':
107 return $this->__searchLanguage();
108
109 default:
110 throw new InvalidArgumentException('ilMDSearch: no valid mode given');
111 }
112 }
113
115 {
116 $this->searchObjectProperties('title', 'description');
118 }
119
120 public function __searchTitle(): ilSearchResult
121 {
122 return $this->searchObjectProperties('title');
123 }
124
126 {
127 return $this->searchObjectProperties('description');
128 }
129
130 protected function searchObjectProperties(string ...$fields): ilSearchResult
131 {
132 $this->setFields($fields);
133
134 $and = ("AND type " . $this->__getInStatement($this->getFilter()));
135 $where = $this->__createObjectPropertiesWhereCondition(...$fields);
136 $locate = $this->__createLocateString();
137
138 $query = "SELECT obj_id,type " .
139 $locate .
140 "FROM object_data " .
141 $where . " " . $and . ' ' .
142 "ORDER BY obj_id DESC";
143
144 $res = $this->db->query($query);
145 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
146 $this->search_result->addEntry(
147 (int) $row->obj_id,
148 (string) $row->type,
149 $this->__prepareFound($row)
150 );
151 }
152
154 }
155
156 public function __searchGeneral(): ?ilSearchResult
157 {
158 global $DIC;
159
160 $ilDB = $DIC->database();
161
162 $coverage_query = $general_query = '';
163 if ($this->options['lom_coverage'] ?? null) {
164 $this->setFields(array('coverage'));
165 $and = $this->__createCoverageAndCondition();
166 $locate = $this->__createLocateString();
167 $coverage_query = "SELECT rbac_id,obj_type,obj_id " .
168 $locate . " " .
169 "FROM il_meta_coverage " .
170 "WHERE obj_type " . $this->__getInStatement($this->getFilter()) . " " .
171 $and;
172 }
173 if ($this->options['lom_structure'] ?? null) {
174 $and = ("AND general_structure = " . $ilDB->quote($this->options['lom_structure'], ilDBConstants::T_TEXT) . " ");
175 $general_query = "SELECT rbac_id,obj_type,obj_id " .
176 "FROM il_meta_general " .
177 "WHERE obj_type " . $this->__getInStatement($this->getFilter()) . " " .
178 $and;
179 }
180
181 $query = $this->joinOnRessourceIDs($general_query, $coverage_query);
182 if ($query === '') {
183 return null;
184 }
185
186 $res = $this->db->query($query);
187 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
188 if ($this->options['lom_coverage'] ?? null) {
189 $found = $this->__prepareFound($row);
190 if (!in_array(0, $found)) {
191 $this->search_result->addEntry(
192 (int) $row->rbac_id,
193 (string) $row->obj_type,
194 $found,
195 (int) $row->obj_id,
196 (string) $row->obj_type
197 );
198 }
199 } else {
200 $this->search_result->addEntry(
201 (int) $row->rbac_id,
202 (string) $row->obj_type,
203 array(),
204 (int) $row->obj_id,
205 (string) $row->obj_type
206 );
207 }
208 }
209
211 }
212
214 {
215 if (!($this->options['lom_language'] ?? null)) {
216 return null;
217 }
218
219 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_language " .
220 "WHERE language = " . $this->db->quote($this->options['lom_language'], 'text') . " " .
221 "AND obj_type " . $this->__getInStatement($this->getFilter()) . ' ' .
222 "AND parent_type = 'meta_general'";
223
224 $res = $this->db->query($query);
225 #var_dump("<pre>",$query,"<pre>");
226 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
227 $this->search_result->addEntry(
228 (int) $row->rbac_id,
229 (string) $row->obj_type,
230 array(),
231 (int) $row->obj_id,
232 (string) $row->obj_type
233 );
234 }
236 }
237
239 {
240 if (!($this->options['lom_role'] ?? null)) {
241 return null;
242 }
243
244 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_contribute " .
245 "WHERE role = " . $this->db->quote($this->options['lom_role'], 'text') . " " .
246 "AND obj_type " . $this->__getInStatement($this->getFilter());
247
248 $res = $this->db->query($query);
249 #var_dump("<pre>",$query,"<pre>");
250 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
251 $this->search_result->addEntry(
252 (int) $row->rbac_id,
253 (string) $row->obj_type,
254 array(),
255 (int) $row->obj_id,
256 (string) $row->obj_type
257 );
258 }
260 }
261
262 public function __searchEntity(): ?ilSearchResult
263 {
264 $this->setFields(array('entity'));
265
266 $and = ("AND obj_type " . $this->__getInStatement($this->getFilter()));
267 $where = $this->__createEntityWhereCondition();
268 $locate = $this->__createLocateString();
269
270 $query = "SELECT rbac_id,obj_id,obj_type " .
271 $locate .
272 "FROM il_meta_entity " .
273 $where . " " . $and . ' ';
274
275 $res = $this->db->query($query);
276 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
277 $found = $this->__prepareFound($row);
278 if (!in_array(0, $found)) {
279 $this->search_result->addEntry(
280 (int) $row->rbac_id,
281 (string) $row->obj_type,
282 $found,
283 (int) $row->obj_id,
284 (string) $row->obj_type
285 );
286 }
287 }
288
290 }
291
292
293
295 {
296 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_or_composite " .
297 "WHERE obj_type " . $this->__getInStatement($this->getFilter());
298
299 $os_query = $browser_query = '';
300 if ($this->options['lom_operating_system'] ?? null) {
301 $os_query = $query . " AND type = 'operating system' AND " .
302 "name = " . $this->db->quote($this->options['lom_operating_system'], ilDBConstants::T_TEXT);
303 }
304 if ($this->options['lom_browser'] ?? null) {
305 $browser_query = $query . " AND type = 'browser' AND " .
306 "name = " . $this->db->quote($this->options['lom_browser'], ilDBConstants::T_TEXT);
307 }
308
309 $query = $this->joinOnRessourceIDs($os_query, $browser_query);
310 if ($query === '') {
311 return null;
312 }
313
314 $res = $this->db->query($query);
315 #var_dump("<pre>",$query,"<pre>");
316 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
317 $this->search_result->addEntry(
318 (int) $row->rbac_id,
319 (string) $row->obj_type,
320 array(),
321 (int) $row->obj_id,
322 (string) $row->obj_type
323 );
324 }
326 }
327
329 {
330 $query_start = "SELECT rbac_id,obj_id,obj_type ";
331 $and = " AND obj_type " . $this->__getInStatement($this->getFilter());
332
333 $ed_query = $lr_type_query = $end_user_query = $context_query = '';
334 if ($where = $this->__createEducationalWhere()) {
335 $ed_query = $query_start . 'FROM il_meta_educational ' . $where . $and;
336 }
337 if ($this->options['lom_resource'] ?? null) {
338 $where = " WHERE learning_resource_type = " . $this->db->quote($this->options['lom_resource'], 'text');
339 $lr_type_query = $query_start . 'FROM il_meta_lr_type ' . $where . $and;
340 }
341 if ($this->options['lom_user_role'] ?? null) {
342 $where = " WHERE intended_end_user_role = " . $this->db->quote($this->options['lom_user_role'], 'text');
343 $end_user_query = $query_start . 'FROM il_meta_end_usr_role ' . $where . $and;
344 }
345 if ($this->options['lom_context'] ?? null) {
346 $where = " WHERE context = " . $this->db->quote($this->options['lom_context'], 'text');
347 $context_query = $query_start . 'FROM il_meta_context ' . $where . $and;
348 }
349
350 $query = $this->joinOnRessourceIDs(
351 $ed_query,
352 $lr_type_query,
353 $end_user_query,
354 $context_query
355 );
356 if ($query === '') {
357 return null;
358 }
359
360 $res = $this->db->query($query);
361 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
362 $this->search_result->addEntry(
363 (int) $row->rbac_id,
364 (string) $row->obj_type,
365 array(),
366 (int) $row->obj_id,
367 (string) $row->obj_type
368 );
369 }
371 }
372
374 {
375 if (
376 !($this->options['typ_age_1'] ?? null) or
377 !($this->options['typ_age_2'] ?? null)
378 ) {
379 return null;
380 }
381
382 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_typical_age_range " .
383 "WHERE typical_age_range_min >= '" . (int) $this->options['typ_age_1'] . "' " .
384 "AND typical_age_range_max <= '" . (int) $this->options['typ_age_2'] . "'";
385
386
387 $res = $this->db->query($query);
388 #var_dump("<pre>",$query,"<pre>");
389 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
390 $this->search_result->addEntry(
391 (int) $row->rbac_id,
392 (string) $row->obj_type,
393 array(),
394 (int) $row->obj_id,
395 (string) $row->obj_type
396 );
397 }
399 }
400
401 public function __searchRights(): ?ilSearchResult
402 {
403 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_rights ";
404
405 if (!strlen($where = $this->__createRightsWhere())) {
406 return null;
407 }
408 $and = ("AND obj_type " . $this->__getInStatement($this->getFilter()));
409 $query = $query . $where . $and;
410 $res = $this->db->query($query);
411 #var_dump("<pre>",$query,"<pre>");
412 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
413 $this->search_result->addEntry(
414 (int) $row->rbac_id,
415 (string) $row->obj_type,
416 array(),
417 (int) $row->obj_id,
418 (string) $row->obj_type
419 );
420 }
422 }
423
425 {
426 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_classification ";
427
428 if (!strlen($where = $this->__createClassificationWhere())) {
429 return null;
430 }
431 $and = ("AND obj_type " . $this->__getInStatement($this->getFilter()));
432 $query = $query . $where . $and;
433 $res = $this->db->query($query);
434 #var_dump("<pre>",$query,"<pre>");
435 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
436 $this->search_result->addEntry(
437 (int) $row->rbac_id,
438 (string) $row->obj_type,
439 array(),
440 (int) $row->obj_id,
441 (string) $row->obj_type
442 );
443 }
445 }
446
447 public function __searchTaxon(): ?ilSearchResult
448 {
449 $this->setFields(array('taxon'));
450
451 $and = ("AND obj_type " . $this->__getInStatement($this->getFilter()));
452 $where = $this->__createTaxonWhereCondition();
453 $locate = $this->__createLocateString();
454
455 $query = "SELECT rbac_id,obj_id,obj_type " .
456 $locate .
457 "FROM il_meta_taxon " .
458 $where . " " . $and . ' ';
459
460 $res = $this->db->query($query);
461 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
462 $found = $this->__prepareFound($row);
463 if (!in_array(0, $found)) {
464 $this->search_result->addEntry(
465 (int) $row->rbac_id,
466 (string) $row->obj_type,
467 $found,
468 (int) $row->obj_id,
469 (string) $row->obj_type
470 );
471 }
472 }
473
475 }
476
477 public function __searchKeyword(bool $a_in_classification = false): ilSearchResult
478 {
479 $this->setFields(array('keyword'));
480
481 $and = ("AND obj_type " . $this->__getInStatement($this->getFilter()));
482 if ($a_in_classification) {
483 $and .= " AND parent_type = 'meta_classification' ";
484 }
485 $where = $this->__createKeywordWhereCondition();
486 $locate = $this->__createLocateString();
487
488 $query = "SELECT rbac_id,obj_id,obj_type " .
489 $locate .
490 "FROM il_meta_keyword " .
491 $where . " " . $and . ' ';
492
493 $res = $this->db->query($query);
494 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
495 $found = $this->__prepareFound($row);
496 if (!in_array(0, $found) or !$a_in_classification) {
497 $this->search_result->addEntry(
498 (int) $row->rbac_id,
499 (string) $row->obj_type,
500 $found,
501 (int) $row->obj_id,
502 (string) $row->obj_type
503 );
504 }
505 }
506
508 }
510 {
511 $this->setFields(array('meta_version'));
512
513 $locate = '';
514 if ($this->options['lom_version'] ?? null) {
515 $where = $this->__createLifecycleWhereCondition();
516 $locate = $this->__createLocateString();
517 } else {
518 $where = "WHERE 1 = 1 ";
519 }
520 $and = ("AND obj_type " . $this->__getInStatement($this->getFilter()));
521
522 if ($this->options['lom_status'] ?? null) {
523 $and .= (" AND lifecycle_status = " . $this->db->quote($this->options['lom_status'], 'text') . "");
524 }
525
526 $query = "SELECT rbac_id,obj_id,obj_type " .
527 $locate .
528 "FROM il_meta_lifecycle " .
529 $where . " " . $and . ' ';
530
531 $res = $this->db->query($query);
532 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
533 $found = $this->__prepareFound($row);
534 if (!in_array(0, $found)) {
535 $this->search_result->addEntry(
536 (int) $row->rbac_id,
537 (string) $row->obj_type,
538 $found,
539 (int) $row->obj_id,
540 (string) $row->obj_type
541 );
542 }
543 }
544
546 }
547
548 public function __searchFormat(): ?ilSearchResult
549 {
550 if (!($this->options['lom_format'] ?? null)) {
551 return null;
552 }
553
554 $query = "SELECT rbac_id,obj_id,obj_type FROM il_meta_format " .
555 "WHERE format LIKE(" . $this->db->quote($this->options['lom_format'], ilDBConstants::T_TEXT) . ") " .
556 "AND obj_type " . $this->__getInStatement($this->getFilter());
557
558 $res = $this->db->query($query);
559 #var_dump("<pre>",$query,"<pre>");
560 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
561 $this->search_result->addEntry(
562 (int) $row->rbac_id,
563 (string) $row->obj_type,
564 array(),
565 (int) $row->obj_id,
566 (string) $row->obj_type
567 );
568 }
570 }
571
572
573 public function __createRightsWhere(): string
574 {
575 $counter = 0;
576 $where = 'WHERE ';
577
578
579 if ($this->options['lom_costs'] ?? null) {
580 $and = $counter++ ? 'AND ' : ' ';
581 $where .= ($and . "costs = " . $this->db->quote($this->options['lom_costs'], 'text') . " ");
582 }
583 if ($this->options['lom_copyright'] ?? null) {
584 $and = $counter++ ? 'AND ' : ' ';
585 $where .= ($and . "cpr_and_or = " . $this->db->quote($this->options['lom_copyright'], 'text') . " ");
586 }
587 return $counter ? $where : '';
588 }
589 public function __createClassificationWhere(): string
590 {
591 $counter = 0;
592 $where = 'WHERE ';
593
594
595 if ($this->options['lom_purpose'] ?? null) {
596 $and = $counter++ ? 'AND ' : ' ';
597 $where .= ($and . "purpose = " . $this->db->quote($this->options['lom_purpose'], ilDBConstants::T_TEXT) . " ");
598 }
599 return $counter ? $where : '';
600 }
601 public function __createEducationalWhere(): string
602 {
603 $counter = 0;
604 $where = 'WHERE ';
605
606
607 if ($this->options['lom_interactivity'] ?? null) {
608 $and = $counter++ ? 'AND ' : ' ';
609 $where .= ($and . "interactivity_type = " . $this->db->quote($this->options['lom_interactivity'], 'text') . " ");
610 }
611 if (
612 ($this->options['lom_level_start'] ?? null) or
613 ($this->options['lom_level_end'] ?? null)) {
614 $and = $counter++ ? 'AND ' : ' ';
615
616 $fields = $this->__getDifference(
617 (int) $this->options['lom_level_start'],
618 (int) $this->options['lom_level_end'],
619 array('VeryLow','Low','Medium','High','VeryHigh')
620 );
621
622 $where .= ($and . "interactivity_level " . $this->__getInStatement($fields));
623 }
624 if (
625 ($this->options['lom_density_start'] ?? null) or
626 ($this->options['lom_density_end'] ?? null)
627 ) {
628 $and = $counter++ ? 'AND ' : ' ';
629
630 $fields = $this->__getDifference(
631 (int) $this->options['lom_density_start'],
632 (int) $this->options['lom_density_end'],
633 array('VeryLow','Low','Medium','High','VeryHigh')
634 );
635
636 $where .= ($and . "semantic_density " . $this->__getInStatement($fields));
637 }
638 if (
639 ($this->options['lom_difficulty_start'] ?? null) or
640 ($this->options['lom_difficulty_end'] ?? null)
641 ) {
642 $and = $counter++ ? 'AND ' : ' ';
643
644 $fields = $this->__getDifference(
645 (int) $this->options['lom_difficulty_start'],
646 (int) $this->options['lom_difficulty_end'],
647 array('VeryEasy','Easy','Medium','Difficult','VeryDifficult')
648 );
649
650 $where .= ($and . "difficulty " . $this->__getInStatement($fields));
651 }
652
653 return $counter ? $where : '';
654 }
655
659 public function __getDifference(int $a_val1, int $a_val2, array $options): array
660 {
661 $a_val2 = $a_val2 ?: count($options);
662 // Call again if a > b
663 if ($a_val1 > $a_val2) {
664 return $this->__getDifference($a_val2, $a_val1, $options);
665 }
666
667 $counter = 0;
668 $fields = [];
669 foreach ($options as $option) {
670 if ($a_val1 > ++$counter) {
671 continue;
672 }
673 if ($a_val2 < $counter) {
674 break;
675 }
676 $fields[] = $option;
677 }
678 return $fields;
679 }
680
681 public function __getInStatement(array $a_fields): string
682 {
683 if (!$a_fields) {
684 return '';
685 }
686 $in = " IN ('";
687 $in .= implode("','", $a_fields);
688 $in .= "') ";
689
690 return $in;
691 }
692
693 protected function joinOnRessourceIDs(string ...$individual_queries): string
694 {
695 $non_empty_queries = [];
696 foreach ($individual_queries as $query) {
697 if ($query !== '') {
698 $non_empty_queries[] = $query;
699 }
700 }
701
702 if (count($non_empty_queries) < 2) {
703 return $non_empty_queries[0] ?? '';
704 }
705
706 $total_query = '';
707 foreach ($non_empty_queries as $query) {
708 if ($total_query === '') {
709 $total_query = $query;
710 continue;
711 }
712 $total_query = "SELECT t1.rbac_id, t1.obj_type, t1.obj_id " .
713 "FROM (" . $total_query . ") AS t1 JOIN (" . $query .
714 ") AS t2 ON t1.rbac_id = t2.rbac_id AND t1.obj_type = t2.obj_type AND t1.obj_id = t2.obj_id";
715 }
716 return $total_query;
717 }
718}
setFields(array $a_fields)
ilSearchResult $search_result
__searchKeyword(bool $a_in_classification=false)
searchObjectProperties(string ... $fields)
__getInStatement(array $a_fields)
__getDifference(int $a_val1, int $a_val2, array $options)
joinOnRessourceIDs(string ... $individual_queries)
setOptions(array &$options)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$res
Definition: ltiservices.php:69
global $DIC
Definition: shib_login.php:26
$counter