ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
Processor.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
26use ILIAS\MetaData\Elements\Factory as ElementFactory;
41
43{
44 protected ElementFactory $element_factory;
49 protected ElementVocabHelper $element_vocab_helper;
50 protected \ilLogger $logger;
51
52 public function __construct(
53 ElementFactory $element_factory,
58 ElementVocabHelper $element_vocab_helper,
60 ) {
61 $this->element_factory = $element_factory;
62 $this->marker_factory = $marker_factory;
63 $this->structure_set = $structure_set;
64 $this->data_validator = $data_validator;
65 $this->dictionary = $dictionary;
66 $this->element_vocab_helper = $element_vocab_helper;
67 $this->logger = $logger;
68 }
69
71 {
72 return $this->element_factory->set(
73 $set->getRessourceID(),
74 $this->getCleanRoot($set)
75 );
76 }
77
78 protected function getCleanRoot(
79 SetInterface $set
81 $root = $set->getRoot();
82 if (!$this->data_validator->isValid($root, true)) {
83 throw new \ilMDRepositoryException('Invalid data on root');
84 }
85 return $this->element_factory->root(
86 $root->getDefinition(),
87 ...$this->getFinishedAndCleanSubElements($root, 0)
88 );
89 }
90
95 ElementInterface $element,
96 int $depth
97 ): \Generator {
98 if ($depth > 20) {
99 throw new \ilMDStructureException('LOM Structure is nested to deep.');
100 }
101 $sub_names = [];
102 foreach ($element->getSubElements() as $sub) {
103 $name = $sub->getDefinition()->name();
104 if ($sub->isScaffold()) {
105 continue;
106 }
107 if ($sub->getDefinition()->unique() && in_array($name, $sub_names)) {
108 $this->throwErrorOrLog($sub, 'duplicate of unique element.');
109 continue;
110 }
111 if ($this->data_validator->isValid($sub, true)) {
112 $sub_names[] = $name;
113 yield $this->element_factory->element(
114 $sub->getMDID(),
115 $sub->getDefinition(),
116 $sub->getData()->value(),
117 $this->lookUpVocabSlotForElement($sub),
118 ...$this->getFinishedAndCleanSubElements($sub, $depth + 1)
119 );
120 continue;
121 }
122 $message = $sub->getData()->value() . ' is not valid as ' .
123 $sub->getData()->type()->value . ' data.';
124 $this->throwErrorOrLog($sub, $message);
125 }
126 }
127
128 protected function lookUpVocabSlotForElement(ElementInterface $element): SlotIdentifier
129 {
130 if (
131 $element->getDefinition()->dataType() !== Type::VOCAB_VALUE &&
132 $element->getDefinition()->dataType() !== Type::STRING
133 ) {
135 }
136 return $this->element_vocab_helper->slotForElement($element);
137 }
138
139 public function cleanMarkers(SetInterface $set): void
140 {
141 $this->checkMarkerOnElement($set->getRoot(), true, 0);
142 }
143
144 public function checkMarkers(SetInterface $set): void
145 {
146 $this->checkMarkerOnElement($set->getRoot(), false, 0);
147 }
148
149 protected function checkMarkerOnElement(
150 ElementInterface $element,
151 bool $replace_by_neutral,
152 int $depth
153 ): void {
154 if ($depth > 20) {
155 throw new \ilMDStructureException('LOM Structure is nested to deep.');
156 }
157 if (!($element instanceof MarkableInterface) || !$element->isMarked()) {
158 return;
159 }
160 $marker = $element->getMarker();
161 if (
162 $marker->action() === Action::CREATE_OR_UPDATE &&
163 !$this->data_validator->isValid($element, false)
164 ) {
165 $message = $marker->dataValue() . ' is not valid as ' .
166 $element->getDefinition()->dataType()->value . ' data.';
167 $this->throwErrorOrLog($element, $message, !$replace_by_neutral);
168 $element->mark($this->marker_factory, Action::NEUTRAL);
169 }
170 foreach ($this->dictionary->tagsForElement($element) as $tag) {
171 $this->checkMarkerAgainstTag($tag, $element, $marker, $replace_by_neutral);
172 }
173 foreach ($element->getSubElements() as $sub) {
174 $this->checkMarkerOnElement($sub, $replace_by_neutral, $depth + 1);
175 }
176 }
177
178 protected function checkMarkerAgainstTag(
179 TagInterface $tag,
180 ElementInterface $element,
181 MarkerInterface $marker,
182 bool $replace_by_neutral
183 ): void {
184 switch ($tag->restriction()) {
185 case Restriction::PRESET_VALUE:
186 if (
187 $this->willBeCreated($element, $marker) &&
188 $marker->dataValue() !== $tag->value()
189 ) {
190 $this->throwErrorOrLog(
191 $element,
192 'can only be created with preset value ' . $tag->value(),
193 !$replace_by_neutral
194 );
195 $element->mark($this->marker_factory, Action::NEUTRAL);
196 }
197 break;
198
199 case Restriction::NOT_DELETABLE:
200 if ($marker->action() === Action::DELETE) {
201 $this->throwErrorOrLog($element, 'cannot be deleted.', !$replace_by_neutral);
202 $element->mark($this->marker_factory, Action::NEUTRAL);
203 }
204 break;
205
207 if (
208 $marker->action() === Action::CREATE_OR_UPDATE &&
209 $element->getMDID() !== NoID::SCAFFOLD
210 ) {
211 $this->throwErrorOrLog($element, 'cannot be edited.', !$replace_by_neutral);
212 $element->mark($this->marker_factory, Action::NEUTRAL);
213 }
214 break;
215 }
216 }
217
218 protected function willBeCreated(
219 ElementInterface $element,
220 MarkerInterface $marker
221 ): bool {
222 return $element->getMDID() === NoID::SCAFFOLD && (
223 $marker->action() === Action::CREATE_OR_UPDATE ||
224 $marker->action() === Action::NEUTRAL
225 );
226 }
227
228 protected function throwErrorOrLog(
229 ElementInterface $element,
230 string $message,
231 bool $throw_error = false
232 ): void {
233 $id = $element->getMDID();
234 $id = is_int($id) ? (string) $id : $id->value;
235 $message = $element->getDefinition()->name() . ' (ID ' . $id . '): ' . $message;
236 if ($super = $element->getSuperElement()) {
237 $message = $super->getDefinition()->name() . ': ' . $message;
238 }
239 if ($throw_error) {
240 throw new \ilMDRepositoryException('Invalid marker on element ' . $message);
241 }
242 $this->logger->info('Skipping element ' . $message);
243 }
244}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(ElementFactory $element_factory, MarkerFactoryInterface $marker_factory, StructureSetInterface $structure_set, DataValidatorInterface $data_validator, DictionaryInterface $dictionary, ElementVocabHelper $element_vocab_helper, \ilLogger $logger)
Definition: Processor.php:52
checkMarkerOnElement(ElementInterface $element, bool $replace_by_neutral, int $depth)
Definition: Processor.php:149
getFinishedAndCleanSubElements(ElementInterface $element, int $depth)
Definition: Processor.php:94
throwErrorOrLog(ElementInterface $element, string $message, bool $throw_error=false)
Definition: Processor.php:228
checkMarkerAgainstTag(TagInterface $tag, ElementInterface $element, MarkerInterface $marker, bool $replace_by_neutral)
Definition: Processor.php:178
lookUpVocabSlotForElement(ElementInterface $element)
Definition: Processor.php:128
finishAndCleanData(SetInterface $set)
Returns a new metadata set, identical to the one given but with vocab slots in data filled out,...
Definition: Processor.php:70
checkMarkers(SetInterface $set)
Checks whether the proposed manipulations on the set via markers are valid.
Definition: Processor.php:144
cleanMarkers(SetInterface $set)
Checks whether the proposed manipulations on the set via markers are valid.
Definition: Processor.php:139
willBeCreated(ElementInterface $element, MarkerInterface $marker)
Definition: Processor.php:218
Component logger with individual log levels by component id.
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getDefinition()
Defining properties of the metadata element.
mark(MarkerFactoryInterface $factory, Action $action, string $data_value='')
Leaves a trail of markers from this element up to the root element, or up to the first already marked...
getRoot()
Returns the root element of the metadata set.
getRessourceID()
Contains the information needed to identify the ILIAS object this metadata set belongs to.
if(!file_exists('../ilias.ini.php'))
$message
Definition: xapiexit.php:31