ILIAS  trunk Revision v11.0_alpha-1715-g7fc467680fb
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
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 string KEYWORDS = 'keywords';
42  public const string GENERAL = 'general';
43  public const string AUTHORS = 'authors';
44  public const string RIGHTS = 'rights';
45  public const string TYPICAL_LEARNING_TIME = 'tlt';
46  public const string FIRST_AUTHOR = 'first_author';
47  public const string SECOND_AUTHOR = 'second_author';
48  public const string THIRD_AUTHOR = 'third_author';
49 
50  public const string CUSTOM_CP = 'custom_cp';
51  public const string CUSTOM_CP_DESCRIPTION = 'custom_cp_description';
52  public const string 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(false);
250  $modal_with_oer_warning = $this->getChangeCopyrightModal(true);
251  $signal = $modal->getShowSignal();
252  $signal_with_oer_warning = $modal_with_oer_warning->getShowSignal();
253 
254  yield ContentType::MODAL => $modal;
255  yield ContentType::MODAL => $modal_with_oer_warning;
256  yield ContentType::JS_SOURCE => 'assets/js/ilMetaCopyrightListener.js';
257  yield ContentType::FORM => $this->getCopyrightSection(
258  $set,
259  $signal,
260  $signal_with_oer_warning
261  );
262  }
263 
264  protected function getChangeCopyrightModal(bool $with_oer_warning): InterruptiveModal
265  {
266  $message = $this->presenter->utilities()->txt("meta_copyright_change_info");
267  if ($with_oer_warning) {
268  $message .= "<br/><br/>" . $this->presenter->utilities()->txt("meta_copyright_change_oer_info");
269  }
270  $modal = $this->ui_factory->modal()->interruptive(
271  $this->presenter->utilities()->txt("meta_copyright_change_warning_title"),
272  $message,
273  (string) $this->link_factory->custom(Command::UPDATE_DIGEST)->get()
274  );
275 
276  return $modal;
277  }
278 
279  protected function getCopyrightSection(
280  SetInterface $set,
281  Signal $signal,
282  Signal $signal_with_oer_warning
283  ): Section {
284  $ff = $this->ui_factory->input()->field();
285 
286  $cp_description_el = $this->navigator_factory->navigator(
287  $this->path_collection->copyright(),
288  $set->getRoot()
289  )->lastElementAtFinalStep();
290  $cp_description = $cp_description_el?->getData()->value();
291 
292  $current_id = $this->copyright_handler->extractCPEntryID((string) $cp_description);
293  $default_id = 0;
294  $options = [];
295  $outdated = [];
296  $potential_oer_values = [];
297  $current_id_exists = false;
298  $is_custom = !is_null($cp_description) && !$current_id;
299 
300  foreach ($this->copyright_handler->getCPEntries() as $entry) {
301  if ($entry->isDefault()) {
302  $default_id = $entry->id();
303  }
304  if ($current_id === $entry->id()) {
305  $current_id_exists = true;
306  }
307 
308  $identifier = $this->copyright_handler->createIdentifierForID($entry->id());
309 
310  //give the option to block harvesting
311  $sub_inputs = [];
312  if (
313  $this->copyright_handler->isObjectTypeHarvested($set->getRessourceID()->type()) &&
314  $this->copyright_handler->isCopyrightTemplateActive($entry)
315  ) {
316  $sub_inputs[self::OER_BLOCKED] = $ff
317  ->checkbox(
318  $this->presenter->utilities()->txt('meta_oer_blocked'),
319  $this->presenter->utilities()->txt('meta_oer_blocked_info')
320  )
321  ->withValue(
322  $this->copyright_handler->isOerHarvesterBlocked($set->getRessourceID()->objID())
323  );
324  $potential_oer_values[] = $identifier;
325  }
326 
327  $option = $ff->group($sub_inputs, $entry->title(), $entry->description());
328 
329  // outdated entries throw an error when selected
330  if ($entry->isOutdated()) {
331  $option = $option->withLabel(
332  '(' . $this->presenter->utilities()->txt('meta_copyright_outdated') .
333  ') ' . $entry->title()
334  );
335  $outdated[] = $identifier;
336  }
337  $options[$identifier] = $option;
338  }
339 
340  //custom input as the last option
341  $custom_text = $ff
342  ->textarea($this->presenter->utilities()->txt('meta_description'))
343  ->withValue($is_custom ? (string) $cp_description : '');
344  $custom = $ff->group(
345  [self::CUSTOM_CP_DESCRIPTION => $custom_text],
346  $this->presenter->utilities()->txt('meta_cp_own')
347  );
348  $options[self::CUSTOM_CP] = $custom;
349 
350  $value = self::CUSTOM_CP;
351  if (!$is_custom) {
352  $id = ($current_id && $current_id_exists) ? $current_id : $default_id;
353  $value = $this->copyright_handler->createIdentifierForID($id);
354  }
355 
356  $copyright = $ff
357  ->switchableGroup(
358  $options,
359  $this->presenter->utilities()->txt('meta_copyright')
360  )
361  ->withValue($value)
362  ->withAdditionalOnLoadCode(
363  function ($id) use ($signal, $signal_with_oer_warning, $potential_oer_values) {
364  return 'il.MetaDataCopyrightListener.init(\'' .
365  $signal . '\',\'' .
366  $signal_with_oer_warning . '\',\'' .
367  json_encode($potential_oer_values) . '\',\'' .
368  $id . '\');';
369  }
370  )->withAdditionalTransformation(
371  $this->refinery->custom()->constraint(
372  function ($v) use ($outdated) {
373  if (in_array($v[0], $outdated, true)) {
374  return false;
375  }
376  return true;
377  },
378  $this->presenter->utilities()->txt('meta_copyright_outdated_error')
379  )
380  );
381 
382  return $ff->section(
383  [$copyright],
384  $this->presenter->utilities()->txt('meta_rights')
385  );
386  }
387 
388  protected function getTypicalLearningTimeSection(
389  SetInterface $set
390  ): Section {
391  $ff = $this->ui_factory->input()->field();
392  $inputs = [];
393 
394  $tlt_el = $this->navigator_factory->navigator(
395  $path = $this->path_collection->firstTypicalLearningTime(),
396  $set->getRoot()
397  )->lastElementAtFinalStep();
398  $matches = iterator_to_array(
399  $this->data_helper->durationToIterator($tlt_el?->getData()?->value() ?? '')
400  );
401  $num = $ff->numeric('placeholder')
402  ->withAdditionalTransformation($this->refinery->int()->isGreaterThanOrEqual(0));
403  $labels = [
404  $this->presenter->utilities()->txt('years'),
405  $this->presenter->utilities()->txt('months'),
406  $this->presenter->utilities()->txt('days'),
407  $this->presenter->utilities()->txt('hours'),
408  $this->presenter->utilities()->txt('minutes'),
409  $this->presenter->utilities()->txt('seconds')
410  ];
411  $inputs = [];
412  foreach ($labels as $key => $label) {
413  $inputs[] = (clone $num)
414  ->withLabel($label)
415  ->withValue($matches[$key] ?? null);
416  }
417  $dh = $this->data_helper;
418  $group = $ff->group(
419  $inputs
420  )->withAdditionalTransformation(
421  $this->refinery->custom()->transformation(function ($vs) use ($dh) {
422  $vs = array_map(fn($v) => is_null($v) ? $v : (int) $v, $vs);
423  return $dh->durationFromIntegers(...$vs);
424  })
425  );
426 
427  return $ff->section(
428  [$path->toString() => $group],
429  $this->presenter->utilities()->txt('meta_typical_learning_time')
430  );
431  }
432 }
__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)
getCopyrightSection(SetInterface $set, Signal $signal, Signal $signal_with_oer_warning)
$path
Definition: ltiservices.php:29
getRoot()
Returns the root element of the metadata set.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getRessourceID()
Contains the information needed to identify the ILIAS object this metadata set belongs to...
withValue($value)
Get an input like this with another value displayed on the client side.
Definition: Group.php:61
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
$message
Definition: xapiexit.php:31