ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
DatabaseReader.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
39 
41 {
47  protected \ilLogger $logger;
48 
49  public function __construct(
50  ElementFactory $element_factory,
51  StructureSetInterface $structure,
52  DictionaryInterface $dictionary,
53  NavigatorFactoryInterface $navigator_factory,
54  DatabaseQuerierInterface $querier,
55  \ilLogger $logger
56  ) {
57  $this->element_factory = $element_factory;
58  $this->structure = $structure;
59  $this->dictionary = $dictionary;
60  $this->navigator_factory = $navigator_factory;
61  $this->querier = $querier;
62  $this->logger = $logger;
63  }
64 
65  public function getMD(RessourceIDInterface $ressource_id): SetInterface
66  {
67  return $this->getSetWithRoot(
68  $ressource_id,
69  ...$this->readSubElements(
70  0,
71  $this->structure->getRoot(),
72  $ressource_id,
73  0
74  )
75  );
76  }
77 
78  public function getMDOnPath(
80  RessourceIDInterface $ressource_id
81  ): SetInterface {
82  $navigator = $this->navigator_factory->structureNavigator(
83  $path,
84  $this->structure->getRoot()
85  );
86  return $this->getSetWithRoot(
87  $ressource_id,
88  ...$this->readSubElements(
89  0,
90  $navigator,
91  $ressource_id,
92  0
93  )
94  );
95  }
96 
100  protected function readSubElements(
101  int $depth,
103  RessourceIDInterface $ressource_id,
104  int $id_from_parent_table,
105  RowInterface $result_row = null
106  ): \Generator {
107  if ($depth > 20) {
108  throw new \ilMDStructureException('LOM Structure is nested to deep.');
109  }
110 
111  foreach ($this->subElements($struct) as $sub) {
112  $tag = $this->tag($sub);
113  $table = $tag?->table() ?? '';
114  $definition = $this->definition($sub);
115 
116  // Read out the next table, if required.
117  $parent_id = $id_from_parent_table;
118  $result_rows = [];
119  if (!is_null($result_row)) {
120  $result_rows = [$result_row];
121  }
122  if ($table && $result_row?->table() !== $table) {
123  $parent_id = $result_row?->id() ?? 0;
124  $result_rows = $this->querier->read(
125  $ressource_id,
126  $parent_id,
127  ...$this->collectTagsFromSameTable($depth, $table, $sub)
128  );
129  }
130 
131  foreach ($result_rows as $row) {
132  $value = $row->value($tag?->dataField() ?? '');
133  if ($definition->dataType() === Type::VOCAB_SOURCE) {
134  $value = LOMVocabInitiator::SOURCE;
135  }
136 
137  if (
138  $definition->dataType() !== Type::NULL &&
139  $value === ''
140  ) {
141  continue;
142  }
143 
150  $sub_elements = iterator_to_array($this->readSubElements(
151  $depth + 1,
152  $sub,
153  $ressource_id,
154  $parent_id,
155  $row
156  ));
157  if (
158  !isset($tag) &&
159  $definition->dataType() !== Type::VOCAB_SOURCE &&
160  count($sub_elements) <= 1 &&
161  (($sub_elements[0] ?? null)?->getData()?->type() ?? Type::VOCAB_SOURCE) === Type::VOCAB_SOURCE
162  ) {
163  continue;
164  }
165 
166  yield $this->element_factory->element(
167  $row->id(),
168  $definition,
169  $value,
170  ...$sub_elements
171  );
172  }
173  }
174  }
175 
179  protected function collectTagsFromSameTable(
180  int $depth,
181  string $table,
183  ): \Generator {
184  if ($depth > 20) {
185  throw new \ilMDStructureException('LOM Structure is nested to deep.');
186  }
187 
188  $tag = $this->tag($struct);
189  if (!is_null($tag) && $table !== $tag?->table()) {
190  return;
191  }
192  if (!is_null($tag)) {
193  yield $tag;
194  }
195 
196  foreach ($this->subElements($struct) as $sub) {
197  yield from $this->collectTagsFromSameTable(
198  $depth + 1,
199  $table,
200  $sub
201  );
202  }
203  }
204 
205  protected function definition(
208  if ($struct instanceof StructureNavigatorInterface) {
209  $struct = $struct->element();
210  }
211  return $struct->getDefinition();
212  }
213 
217  protected function subElements(
219  ): \Generator {
220  if ($struct instanceof StructureElementInterface) {
221  yield from $struct->getSubElements();
222  return;
223  }
224  if ($next_struct = $struct->nextStep()) {
225  yield $next_struct;
226  } else {
227  yield from $struct->element()->getSubElements();
228  }
229  }
230 
231  protected function tag(
233  ): ?TagInterface {
234  if ($struct instanceof StructureNavigatorInterface) {
235  $struct = $struct->element();
236  }
237  return $this->dictionary->tagForElement($struct);
238  }
239 
240  protected function getSetWithRoot(
241  RessourceIDInterface $ressource_id,
242  Element ...$elements
243  ): SetInterface {
244  $root_definition = $this->structure->getRoot()->getDefinition();
245  return $this->element_factory->set(
246  $ressource_id,
247  $this->element_factory->root(
248  $root_definition,
249  ...$elements
250  )
251  );
252  }
253 }
nextStep()
Returns null if there is no next step.
getMD(RessourceIDInterface $ressource_id)
getSetWithRoot(RessourceIDInterface $ressource_id, Element ... $elements)
element()
Returns the element at the current step in the path.
collectTagsFromSameTable(int $depth, string $table, StructureElementInterface|StructureNavigatorInterface $struct)
tag(StructureElementInterface|StructureNavigatorInterface $struct,)
$path
Definition: ltiservices.php:32
getRoot()
Returns the root element of the metadata set.
definition(StructureElementInterface|StructureNavigatorInterface $struct,)
readSubElements(int $depth, StructureElementInterface|StructureNavigatorInterface $struct, RessourceIDInterface $ressource_id, int $id_from_parent_table, RowInterface $result_row=null)
__construct(ElementFactory $element_factory, StructureSetInterface $structure, DictionaryInterface $dictionary, NavigatorFactoryInterface $navigator_factory, DatabaseQuerierInterface $querier, \ilLogger $logger)
getMDOnPath(PathInterface $path, RessourceIDInterface $ressource_id)
subElements(StructureElementInterface|StructureNavigatorInterface $struct,)