19 declare(strict_types=1);
38 protected \ilDBInterface
$db;
56 $paths_parser = $this->paths_parser_factory->forSearch();
58 $quoted_table_alias = $this->
quoteIdentifier($paths_parser->getTableAliasForFilters());
60 $query = $paths_parser->getSelectForQuery() .
' GROUP BY ' . $quoted_table_alias .
'.rbac_id, ' .
61 $quoted_table_alias .
'.obj_id, ' . $quoted_table_alias .
'.obj_type HAVING ' . $where .
65 foreach ($this->
queryDB($query) as $row) {
66 yield $this->ressource_factory->ressourceID(
67 (
int) $row[
'rbac_id'],
69 (
string) $row[
'obj_type']
75 string $quoted_table_alias,
79 foreach ($filters as $filter) {
82 $filter_values[] = $quoted_table_alias .
'.rbac_id = ' . $val;
85 $filter_values[] = $quoted_table_alias .
'.obj_id = ' . $val;
88 $filter_values[] = $quoted_table_alias .
'.obj_type = ' . $val;
90 if (!empty($filter_values)) {
91 $filter_where[] =
'(' . implode(
' AND ', $filter_values) .
')';
95 if (empty($filter_where)) {
99 return ' AND (' . implode(
' OR ', $filter_where) .
')';
103 string $quoted_table_alias,
106 if (is_int($value)) {
109 if (is_string($value)) {
114 case Placeholder::OBJ_ID:
115 return $quoted_table_alias .
'.rbac_id';
117 case Placeholder::SUB_ID:
118 return $quoted_table_alias .
'.obj_id';
120 case Placeholder::TYPE:
121 return $quoted_table_alias .
'.obj_type';
132 if (!is_null($limit) || !is_null($offset)) {
133 $limit = is_null($limit) ? PHP_INT_MAX : $limit;
137 if (!is_null($offset)) {
138 $query_offset =
' OFFSET ' . $this->
quoteInteger($offset);
140 return $query_limit . $query_offset;
149 throw new \ilMDRepositoryException(
'Search clause is nested to deep.');
162 $sub_clauses_for_query = [];
163 foreach ($join_props->subClauses() as $sub_clause) {
167 switch ($join_props->operator()) {
169 $operator_for_query =
'AND';
173 $operator_for_query =
'OR';
177 throw new \ilMDRepositoryException(
'Invalid search operator.');
185 return $negation .
'(' . implode(
' ' . $operator_for_query .
' ', $sub_clauses_for_query) .
')';
190 bool $is_clause_negated,
193 switch ($basic_props->
mode()) {
200 $comparison =
'LIKE ' .
204 case Mode::STARTS_WITH:
205 $comparison =
'LIKE ' .
210 $comparison =
'LIKE ' .
215 throw new \ilMDRepositoryException(
'Invalid search mode.');
220 $mode_negation =
'NOT ';
222 $clause_negation =
'';
223 if ($is_clause_negated) {
224 $clause_negation =
'NOT ';
227 $needs_join_to_base_table = $basic_props->
value() ===
'' || $is_clause_negated;
229 return $clause_negation .
'COUNT(CASE WHEN ' . $mode_negation .
231 ' ' . $comparison .
' THEN 1 END) > 0';
236 $result = $this->db->query($query);
238 while ($row = $this->db->fetchAssoc($result)) {
245 return $this->db->quoteIdentifier($identifier);