19 declare(strict_types=1);
66 protected \ilDBInterface
$db;
88 $from_expression =
'';
90 if (empty($this->path_joins_by_path)) {
91 throw new \ilMDRepositoryException(
'No tables found for search.');
93 count($this->path_joins_by_path) === 1 &&
94 !$this->force_join_to_base_table
97 $from_expression = array_values($this->path_joins_by_path)[0];
98 $path = array_keys($this->path_joins_by_path)[0];
99 if (isset($this->additional_conditions_by_path[
$path])) {
100 $from_expression .=
' WHERE ' .
101 implode(
' AND ', $this->additional_conditions_by_path[$path]);
104 $base_table =
'base';
105 $from_expression =
'il_meta_general AS base';
107 foreach ($this->path_joins_by_path as
$path => $join) {
110 'p' . $path_number .
't1',
112 if (isset($this->additional_conditions_by_path[
$path])) {
113 $condition .=
' AND ' .
114 implode(
' AND ', $this->additional_conditions_by_path[$path]);
116 $from_expression .=
' LEFT JOIN (' . $join .
') ON ' . $condition;
121 return 'SELECT ' . $this->
quoteIdentifier($base_table) .
'.rbac_id, ' .
123 $this->
quoteIdentifier($base_table) .
'.obj_type FROM ' . $from_expression;
128 bool $force_join_to_base_table
130 if (!$this->force_join_to_base_table) {
135 if (isset($this->columns_by_path[$path_string])) {
136 return $this->columns_by_path[$path_string];
139 $data_column_name =
'';
143 foreach ($this->
collectJoinInfos($path, $this->path_number) as $type => $info) {
144 if ($type === self::JOIN_TABLE && !empty($info)) {
147 if ($type === self::JOIN_CONDITION && !empty($info)) {
148 $conditions[] = $info;
150 if ($type === self::COLUMN_NAME && !empty($info)) {
151 $data_column_name = $info;
155 if (count($tables) === 1 && !empty($conditions)) {
156 $this->path_joins_by_path[$path_string] = $tables[0];
162 $this->additional_conditions_by_path[$path_string] = $conditions;
163 $this->path_number++;
164 } elseif (!empty($tables)) {
165 $join = implode(
' JOIN ', $tables);
166 if (!empty($conditions)) {
167 $join .=
' ON ' . implode(
' AND ', $conditions);
169 $this->path_joins_by_path[$path_string] = $join;
170 $this->path_number++;
173 return $this->columns_by_path[$path_string] = $data_column_name;
178 if (empty($this->path_joins_by_path)) {
179 throw new \ilMDRepositoryException(
'No tables found for search.');
181 count($this->path_joins_by_path) === 1 &&
182 !$this->force_join_to_base_table
203 while ($navigator->hasNextStep()) {
205 throw new \ilMDStructureException(
'LOM Structure is nested to deep.');
208 $navigator = $navigator->nextStep();
211 if ($current_tag?->table() && $current_table !== $current_tag?->table()) {
212 $parent_table = $current_table;
213 $current_table = $current_tag->table();
214 $this->checkTable($current_table);
223 $alias = $table_aliases[$current_table];
225 $alias =
'p' . $path_number .
't' . $table_number;
226 $table_aliases[$current_table] = $alias;
229 yield self::JOIN_TABLE => $this->
quoteIdentifier($this->table($current_table)) .
233 if (!$current_tag->hasParent()) {
235 'p' . $path_number .
't1',
240 'p' . $path_number .
't1',
242 $table_aliases[$parent_table],
244 $current_tag->parent()
249 foreach ($navigator->currentStep()->filters() as $filter) {
251 $table_aliases[$current_table],
253 $current_tag?->hasData() ? $current_tag->dataField() :
'',
263 $current_tag?->hasData() ? $current_tag->dataField() :
'' 268 string $first_table_alias,
270 ?
string $parent_table_alias =
null,
271 ?
string $parent_table =
null,
272 ?
string $parent_type =
null 278 if ($table_alias !== $first_table_alias) {
279 $conditions[] = $first_table_alias .
'.rbac_id = ' . $table_alias .
'.rbac_id';
280 $conditions[] = $first_table_alias .
'.obj_id = ' . $table_alias .
'.obj_id';
281 $conditions[] = $first_table_alias .
'.obj_type = ' . $table_alias .
'.obj_type';
284 if (!is_null($parent_table_alias) && !is_null($parent_table)) {
285 $parent_id_column = $parent_table_alias .
'.' .
287 $conditions[] = $parent_id_column .
' = ' . $table_alias .
'.parent_id';
289 if (!is_null($parent_type)) {
290 $conditions[] = $this->
quoteText($parent_type) .
291 ' = ' . $table_alias .
'.parent_type';
294 return implode(
' AND ', $conditions);
305 foreach ($filter->values() as $value) {
311 if (empty($quoted_values)) {
315 switch ($filter->type()) {
316 case FilterType::NULL:
319 case FilterType::MDID:
320 $column = $table_alias .
'.' . $this->
quoteIdentifier($this->IDName($table));
321 return $column .
' IN (' . implode(
', ', $quoted_values) .
')';
324 case FilterType::INDEX:
330 return $column .
' IN (' . implode(
', ', $quoted_values) .
')';
334 throw new \ilMDRepositoryException(
'Unknown filter type: ' . $filter->type()->value);
343 string $quoted_table_alias,
347 if ($data_field !==
'') {
348 $column =
'COALESCE(' . $quoted_table_alias .
'.' . $this->
quoteIdentifier($data_field) .
", '')";
355 return $this->navigator_factory->structureNavigator(
357 $this->structure->getRoot()
363 return $this->dictionary->tagForElement($navigator->
element());
368 return $navigator->
element()->getDefinition()->dataType();
373 return $this->db->quoteIdentifier($identifier);
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null