ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
ContentAssembler.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
37 
39 {
40  // post variables
41  public const KEYWORDS = 'keywords';
42  public const GENERAL = 'general';
43  public const AUTHORS = 'authors';
44  public const RIGHTS = 'rights';
45  public const TYPICAL_LEARNING_TIME = 'tlt';
46  public const FIRST_AUTHOR = 'first_author';
47  public const SECOND_AUTHOR = 'second_author';
48  public const THIRD_AUTHOR = 'third_author';
49 
50  public const CUSTOM_CP = 'custom_cp';
51  public const CUSTOM_CP_DESCRIPTION = 'custom_cp_description';
52  public const OER_BLOCKED = 'oer_blocked_';
53 
57  protected Refinery $refinery;
63 
64  public function __construct(
65  PathFactory $path_factory,
66  NavigatorFactoryInterface $navigator_factory,
67  UIFactory $factory,
68  Refinery $refinery,
69  PresenterInterface $presenter,
70  PathCollection $path_collection,
71  LinkFactory $link_factory,
72  CopyrightHandler $copyright_handler,
73  DataHelperInterface $data_helper
74  ) {
75  $this->path_factory = $path_factory;
76  $this->navigator_factory = $navigator_factory;
77  $this->ui_factory = $factory;
78  $this->refinery = $refinery;
79  $this->presenter = $presenter;
80  $this->path_collection = $path_collection;
81  $this->link_factory = $link_factory;
82  $this->copyright_handler = $copyright_handler;
83  $this->data_helper = $data_helper;
84  }
85 
89  public function get(
90  SetInterface $set,
91  ?RequestForFormInterface $request = null
92  ): \Generator {
93  $sections = [
94  self::GENERAL => $this->getGeneralSection($set),
95  self::AUTHORS => $this->getAuthorsSection($set)
96  ];
97  foreach ($this->getCopyrightContent($set) as $type => $entity) {
98  if ($type === ContentType::FORM) {
99  $sections[self::RIGHTS] = $entity;
100  continue;
101  }
102  yield $type => $entity;
103  }
104  $sections[self::TYPICAL_LEARNING_TIME] = $this->getTypicalLearningTimeSection($set);
105  $form = $this->ui_factory->input()->container()->form()->standard(
106  (string) $this->link_factory->custom(Command::UPDATE_DIGEST)->get(),
107  $sections
108  );
109 
110  if (isset($request)) {
111  $form = $request->applyRequestToForm($form);
112  }
113  yield ContentType::FORM => $form;
114  }
115 
116  protected function getGeneralSection(
117  SetInterface $set
118  ): Section {
119  $ff = $this->ui_factory->input()->field();
120  $root = $set->getRoot();
121  $inputs = [];
122 
123  $title_el = $this->navigator_factory->navigator(
124  $path = $this->path_collection->title(),
125  $root
126  )->lastElementAtFinalStep();
127  $inputs[$path->toString()] = $ff
128  ->text($this->presenter->utilities()->txt('meta_title'))
129  ->withRequired(true)
130  ->withValue($title_el?->getData()?->value() ?? '');
131 
132  $descr_els = $this->navigator_factory->navigator(
133  $descr_path = $this->path_collection->descriptions(),
134  $root
135  )->elementsAtFinalStep();
136  $descr_els = iterator_to_array($descr_els);
137  $label = $this->presenter->utilities()->txt('meta_description');
138  $empty_descr = true;
139  foreach ($descr_els as $el) {
140  $empty_descr = false;
141  $label_with_lang = $label;
142  foreach ($el->getSuperElement()->getSubElements() as $sub) {
143  if (
144  $sub->getDefinition()->name() !== 'language' ||
145  ($value = $sub->getData()->value()) === ''
146  ) {
147  continue;
148  }
149  $label_with_lang .= ' (' . $this->presenter->data()->language($value) . ')';
150  }
151  $inputs[$this->path_factory->toElement($el, true)->toString()] = $ff
152  ->textarea($label_with_lang)
153  ->withValue($el->getData()->value());
154  }
155  if ($empty_descr) {
156  $inputs[$descr_path->toString()] = $ff
157  ->textarea($label);
158  }
159 
160  $langs = [];
161  foreach ($this->data_helper->getAllLanguages() as $key) {
162  $langs[$key] = $this->presenter->data()->language($key);
163  }
164  $lang_input = $ff->select(
165  $this->presenter->utilities()->txt('meta_language'),
166  $langs
167  );
168  $lang_els = $this->navigator_factory->navigator(
169  $langs_path = $this->path_collection->languages(),
170  $root
171  )->elementsAtFinalStep();
172  $empty_langs = true;
173  foreach ($lang_els as $el) {
174  $empty_langs = false;
175  $inputs[$this->path_factory->toElement($el, true)->toString()] = (clone $lang_input)
176  ->withValue($el->getData()->value());
177  }
178  if ($empty_langs) {
179  $inputs[$langs_path->toString()] = clone $lang_input;
180  }
181 
182  $keywords = [];
183  $keyword_els = $this->navigator_factory->navigator(
184  $keywords_path = $this->path_collection->keywords(),
185  $root
186  )->elementsAtFinalStep();
187  foreach ($keyword_els as $el) {
188  if (!$el->isScaffold()) {
189  $keywords[] = $el->getData()->value();
190  }
191  }
192  $inputs[self::KEYWORDS] = $ff->tag(
193  $this->presenter->utilities()->txt('keywords'),
194  $keywords
195  )->withValue($keywords);
196 
197  return $ff->section(
198  $inputs,
199  $this->presenter->utilities()->txt('meta_general')
200  );
201  }
202 
203  protected function getAuthorsSection(
204  SetInterface $set
205  ): Section {
206  $ff = $this->ui_factory->input()->field();
207  $inputs = [];
208 
209  $paths = [
210  $this->path_collection->firstAuthor(),
211  $this->path_collection->secondAuthor(),
212  $this->path_collection->thirdAuthor()
213  ];
214  $labels = [
215  $this->presenter->utilities()->txt('meta_first_author'),
216  $this->presenter->utilities()->txt('meta_second_author'),
217  $this->presenter->utilities()->txt('meta_third_author')
218  ];
219  $post_keys = [
220  self::FIRST_AUTHOR,
221  self::SECOND_AUTHOR,
222  self::THIRD_AUTHOR
223  ];
224  foreach ($paths as $path) {
225  $el = $this->navigator_factory->navigator(
226  $path,
227  $set->getRoot()
228  )->lastElementAtFinalStep();
229  $inputs[array_shift($post_keys)] = $ff
230  ->text(array_shift($labels))
231  ->withValue($el?->getData()?->value() ?? '');
232  }
233 
234  return $ff->section(
235  $inputs,
236  $this->presenter->utilities()->txt('meta_authors')
237  );
238  }
239 
243  protected function getCopyrightContent(
244  SetInterface $set
245  ): \Generator {
246  if (!$this->copyright_handler->isCPSelectionActive()) {
247  return;
248  }
249  $modal = $this->getChangeCopyrightModal();
250  $signal = $modal->getShowSignal();
251 
252  yield ContentType::MODAL => $modal;
253  yield ContentType::JS_SOURCE => 'Services/MetaData/js/ilMetaCopyrightListener.js';
254  yield ContentType::FORM => $this->getCopyrightSection($set, $signal);
255  }
256 
258  {
259  $modal = $this->ui_factory->modal()->interruptive(
260  $this->presenter->utilities()->txt("meta_copyright_change_warning_title"),
261  $this->presenter->utilities()->txt("meta_copyright_change_info"),
262  (string) $this->link_factory->custom(Command::UPDATE_DIGEST)->get()
263  );
264 
265  return $modal;
266  }
267 
268  protected function getCopyrightSection(
269  SetInterface $set,
270  Signal $signal
271  ): Section {
272  $ff = $this->ui_factory->input()->field();
273 
274  $cp_description_el = $this->navigator_factory->navigator(
275  $this->path_collection->copyright(),
276  $set->getRoot()
277  )->lastElementAtFinalStep();
278  $cp_description = $cp_description_el?->getData()->value();
279 
280  $current_id = $this->copyright_handler->extractCPEntryID((string) $cp_description);
281  $default_id = 0;
282  $options = [];
283  $outdated = [];
284  $current_id_exists = false;
285  $is_custom = !is_null($cp_description) && !$current_id;
286 
287  foreach ($this->copyright_handler->getCPEntries() as $entry) {
288  if ($entry->isDefault()) {
289  $default_id = $entry->id();
290  }
291  if ($current_id === $entry->id()) {
292  $current_id_exists = true;
293  }
294 
295  //give the option to block harvesting
296  $sub_inputs = [];
297  if (
298  $this->copyright_handler->doesObjectTypeSupportHarvesting($set->getRessourceID()->type()) &&
299  $this->copyright_handler->isCopyrightTemplateActive($entry)
300  ) {
301  $sub_inputs[self::OER_BLOCKED] = $ff
302  ->checkbox(
303  $this->presenter->utilities()->txt('meta_oer_blocked'),
304  $this->presenter->utilities()->txt('meta_oer_blocked_info')
305  )
306  ->withValue(
307  $this->copyright_handler->isOerHarvesterBlocked($set->getRessourceID()->objID())
308  );
309  }
310 
311  $option = $ff->group($sub_inputs, $entry->title());
312  $identifier = $this->copyright_handler->createIdentifierForID($entry->id());
313 
314  // outdated entries throw an error when selected
315  if ($entry->isOutdated()) {
316  $option = $option->withLabel(
317  '(' . $this->presenter->utilities()->txt('meta_copyright_outdated') .
318  ') ' . $entry->title()
319  );
320  $outdated[] = $identifier;
321  }
322  $options[$identifier] = $option;
323  }
324 
325  //custom input as the last option
326  $custom_text = $ff
327  ->textarea($this->presenter->utilities()->txt('meta_description'))
328  ->withValue($is_custom ? (string) $cp_description : '');
329  $custom = $ff->group(
330  [self::CUSTOM_CP_DESCRIPTION => $custom_text],
331  $this->presenter->utilities()->txt('meta_cp_own')
332  );
333  $options[self::CUSTOM_CP] = $custom;
334 
335  $value = self::CUSTOM_CP;
336  if (!$is_custom) {
337  $id = ($current_id && $current_id_exists) ? $current_id : $default_id;
338  $value = $this->copyright_handler->createIdentifierForID($id);
339  }
340 
341  $copyright = $ff
342  ->switchableGroup(
343  $options,
344  $this->presenter->utilities()->txt('meta_copyright')
345  )
346  ->withValue($value)
347  ->withAdditionalOnLoadCode(
348  function ($id) use ($signal) {
349  return 'il.MetaDataCopyrightListener.init("' .
350  $signal . '","' . $id . '");';
351  }
353  $this->refinery->custom()->constraint(
354  function ($v) use ($outdated) {
355  if (in_array($v[0], $outdated, true)) {
356  return false;
357  }
358  return true;
359  },
360  $this->presenter->utilities()->txt('meta_copyright_outdated_error')
361  )
362  );
363 
364  return $ff->section(
365  [$copyright],
366  $this->presenter->utilities()->txt('meta_rights')
367  );
368  }
369 
370  protected function getTypicalLearningTimeSection(
371  SetInterface $set
372  ): Section {
373  $ff = $this->ui_factory->input()->field();
374  $inputs = [];
375 
376  $tlt_el = $this->navigator_factory->navigator(
377  $path = $this->path_collection->firstTypicalLearningTime(),
378  $set->getRoot()
379  )->lastElementAtFinalStep();
380  $matches = iterator_to_array(
381  $this->data_helper->durationToIterator($tlt_el?->getData()?->value() ?? '')
382  );
383  $num = $ff->numeric('placeholder')
384  ->withAdditionalTransformation($this->refinery->int()->isGreaterThanOrEqual(0));
385  $labels = [
386  $this->presenter->utilities()->txt('years'),
387  $this->presenter->utilities()->txt('months'),
388  $this->presenter->utilities()->txt('days'),
389  $this->presenter->utilities()->txt('hours'),
390  $this->presenter->utilities()->txt('minutes'),
391  $this->presenter->utilities()->txt('seconds')
392  ];
393  $inputs = [];
394  foreach ($labels as $key => $label) {
395  $inputs[] = (clone $num)
396  ->withLabel($label)
397  ->withValue($matches[$key] ?? null);
398  }
399  $dh = $this->data_helper;
400  $group = $ff->group(
401  $inputs
402  )->withAdditionalTransformation(
403  $this->refinery->custom()->transformation(function ($vs) use ($dh) {
404  $vs = array_map(fn ($v) => is_null($v) ? $v : (int) $v, $vs);
405  return $dh->durationFromIntegers(...$vs);
406  })
407  );
408 
409  return $ff->section(
410  [$path->toString() => $group],
411  $this->presenter->utilities()->txt('meta_typical_learning_time')
412  );
413  }
414 }
This describes section inputs.
Definition: Section.php:28
__construct(PathFactory $path_factory, NavigatorFactoryInterface $navigator_factory, UIFactory $factory, Refinery $refinery, PresenterInterface $presenter, PathCollection $path_collection, LinkFactory $link_factory, CopyrightHandler $copyright_handler, DataHelperInterface $data_helper)
$path
Definition: ltiservices.php:32
getRoot()
Returns the root element of the metadata set.
getRessourceID()
Contains the information needed to identify the ILIAS object this metadata set belongs to...
string $key
Consumer key/client ID value.
Definition: System.php:193
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:58
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
getCopyrightSection(SetInterface $set, Signal $signal)