ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
DatabaseManipulator.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
36 
38 {
42  protected \ilLogger $logger;
43 
44  public function __construct(
45  DictionaryInterface $dictionary,
46  DatabaseQuerierInterface $querier,
47  AssignmentFactoryInterface $assignment_factory,
48  \ilLogger $logger
49  ) {
50  $this->dictionary = $dictionary;
51  $this->querier = $querier;
52  $this->assignment_factory = $assignment_factory;
53  $this->logger = $logger;
54  }
55 
56  public function deleteAllMD(RessourceIDInterface $ressource_id): void
57  {
58  $this->querier->deleteAll($ressource_id);
59  }
60 
61  public function manipulateMD(
62  SetInterface $set
63  ): void {
64  foreach ($set->getRoot()->getSubElements() as $sub) {
66  0,
67  $sub
68  ) as $row) {
69  $this->querier->manipulate(
70  $set->getRessourceID(),
71  $row
72  );
73  }
74  }
75  }
76 
77  public function transferMD(SetInterface $from_set, RessourceIDInterface $to_ressource_id): void
78  {
79  foreach ($from_set->getRoot()->getSubElements() as $sub) {
81  0,
82  $sub
83  ) as $row) {
84  $this->querier->manipulate(
85  $to_ressource_id,
86  $row
87  );
88  }
89  }
90  }
91 
96  int $depth,
97  ElementInterface $element,
98  AssignmentRowInterface $current_row = null,
99  bool $delete_all = false
100  ): array {
101  if ($depth > 20) {
102  throw new \ilMDStructureException('LOM Structure is nested to deep.');
103  }
104 
105  $collected_rows = [];
106 
107  $marker = $this->marker($element);
108  if (!isset($marker) && !$delete_all) {
109  return [];
110  }
111 
112  $tag = $this->tag($element);
113  if (!is_null($next_row = $this->getNewRowIfNecessary($element->getMDID(), $tag, $current_row))) {
114  $current_row = $next_row;
115  $collected_rows[] = $next_row;
116  }
117 
118  $action = $marker?->action();
119  if ($delete_all) {
120  $action = MarkerAction::DELETE;
121  }
122  switch ($action) {
123  case MarkerAction::NEUTRAL:
124  if ($element->isScaffold()) {
125  return [];
126  }
127  break;
128 
129  case MarkerAction::CREATE_OR_UPDATE:
130  if (!is_null($tag)) {
131  $this->createOrUpdateElement(
132  $element,
133  $tag,
134  $marker->dataValue(),
135  $current_row
136  );
137  }
138  break;
139 
141  if (!is_null($tag)) {
142  $current_row->addAction($this->assignment_factory->action(
144  $tag
145  ));
146  }
147  $delete_all = true;
148  }
149 
150  foreach ($element->getSubElements() as $sub) {
151  $collected_rows = array_merge(
152  $collected_rows,
154  $depth + 1,
155  $sub,
156  $current_row,
157  $delete_all
158  )
159  );
160  }
161  return $collected_rows;
162  }
163 
165  int $depth,
166  ElementInterface $element,
167  AssignmentRowInterface $current_row = null
168  ): array {
169  if ($depth > 20) {
170  throw new \ilMDStructureException('LOM Structure is nested to deep.');
171  }
172 
173  $collected_rows = [];
174  $marker = $this->marker($element);
175 
176  if ($element->isScaffold() && $marker?->action() !== MarkerAction::CREATE_OR_UPDATE) {
177  return [];
178  }
179  $data_value = !is_null($marker?->dataValue()) ? $marker->dataValue() : $element->getData()->value();
180 
181  $tag = $this->tag($element);
182  if (!is_null($next_row = $this->getNewRowIfNecessary(NoID::SCAFFOLD, $tag, $current_row))) {
183  $current_row = $next_row;
184  $collected_rows[] = $next_row;
185  }
186 
187  if (!is_null($tag)) {
188  $current_row->addAction($this->assignment_factory->action(
189  Action::CREATE,
190  $tag,
191  $data_value
192  ));
193  if (!$current_row->id()) {
194  $current_row->setId($this->querier->nextID($current_row->table()));
195  }
196  }
197 
198  foreach ($element->getSubElements() as $sub) {
199  $collected_rows = array_merge(
200  $collected_rows,
202  $depth + 1,
203  $sub,
204  $current_row
205  )
206  );
207  }
208  return $collected_rows;
209  }
210 
211  protected function getNewRowIfNecessary(
212  NoID|int $md_id,
213  ?TagInterface $tag,
214  ?AssignmentRowInterface $current_row
216  $table = $tag?->table() ?? '';
217  if ($table && $current_row?->table() !== $table) {
218  return $this->assignment_factory->row(
219  $table,
220  is_int($md_id) ? $md_id : 0,
221  $current_row?->id() ?? 0
222  );
223  }
224  return null;
225  }
226 
227  protected function createOrUpdateElement(
228  ElementInterface $element,
229  TagInterface $tag,
230  string $data_value,
232  ): void {
233  if (!$element->isScaffold()) {
234  $row->addAction($this->assignment_factory->action(
235  Action::UPDATE,
236  $tag,
237  $data_value
238  ));
239  } else {
240  $row->addAction($this->assignment_factory->action(
241  Action::CREATE,
242  $tag,
243  $data_value
244  ));
245  if (!$row->id()) {
246  $row->setId($this->querier->nextID($row->table()));
247  }
248  }
249  }
250 
251  protected function tag(
252  ElementInterface $element,
253  ): ?TagInterface {
254  return $this->dictionary->tagForElement($element);
255  }
256 
257  protected function marker(
258  ElementInterface $element
259  ): ?MarkerInterface {
260  if (!($element instanceof MarkableInterface) || !$element->isMarked()) {
261  return null;
262  }
263  return $element->getMarker();
264  }
265 }
addAction(ActionAssignmentInterface $assignment)
Note that this does not clone!
createOrUpdateElement(ElementInterface $element, TagInterface $tag, string $data_value, AssignmentRowInterface $row)
collectRowsForManipulationFromElementAndSubElements(int $depth, ElementInterface $element, AssignmentRowInterface $current_row=null, bool $delete_all=false)
transferMD(SetInterface $from_set, RessourceIDInterface $to_ressource_id)
Transfers the set to object, ignores unmarked scaffolds and delete markers.
collectRowsForTransferFromElementAndSubElements(int $depth, ElementInterface $element, AssignmentRowInterface $current_row=null)
getNewRowIfNecessary(NoID|int $md_id, ?TagInterface $tag, ?AssignmentRowInterface $current_row)
getRoot()
Returns the root element of the metadata set.
getRessourceID()
Contains the information needed to identify the ILIAS object this metadata set belongs to...
isMarked()
Elements can be marked to be created, updated or deleted.
__construct(DictionaryInterface $dictionary, DatabaseQuerierInterface $querier, AssignmentFactoryInterface $assignment_factory, \ilLogger $logger)