ILIAS  release_8 Revision v8.24
class.ilObjectCopyGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23
32{
33 public const SOURCE_SELECTION = 1;
34 public const TARGET_SELECTION = 2;
35 public const SEARCH_SOURCE = 3;
36
37 public const SUBMODE_COMPLETE = 1;
38 public const SUBMODE_CONTENT_ONLY = 2;
39
40 // tabs
41 public const TAB_SELECTION_TARGET_TREE = 1;
42 public const TAB_SELECTION_SOURCE_TREE = 2;
43 public const TAB_SELECTION_MEMBERSHIP = 3;
44
45 // group selection of source or target
46 public const TAB_GROUP_SC_SELECTION = 1;
47
48 protected ilCtrl $ctrl;
49 protected ilTree $tree;
50 protected ilTabsGUI $tabs;
58 protected ilObjUser $user;
60 protected ilLogger $log;
61 protected ilLanguage $lng;
65
68
69 protected int $mode = 0;
71 protected string $type = '';
72 protected array $sources = [];
73 protected array $targets = [];
74 protected array $targets_copy_id = [];
77
78 public function __construct(ImplementsCreationCallback $parent_gui)
79 {
80 global $DIC;
81
82 $this->ctrl = $DIC->ctrl();
83 $this->tree = $DIC->repositoryTree();
84 $this->tabs = $DIC->tabs();
85 $this->toolbar = $DIC->toolbar();
86 $this->tpl = $DIC["tpl"];
87 $this->obj_definition = $DIC["objDefinition"];
88 $this->obj_data_cache = $DIC["ilObjDataCache"];
89 $this->access = $DIC->access();
90 $this->error = $DIC["ilErr"];
91 $this->rbacsystem = $DIC->rbac()->system();
92 $this->user = $DIC->user();
93 $this->rbacreview = $DIC->rbac()->review();
94 $this->log = ilLoggerFactory::getLogger('obj');
95 $this->lng = $DIC->language();
96 $this->request_wrapper = $DIC->http()->wrapper()->query();
97 $this->post_wrapper = $DIC->http()->wrapper()->post();
98 $this->refinery = $DIC->refinery();
99 $this->retriever = new ilObjectRequestRetriever($DIC->http()->wrapper(), $this->refinery);
100
101 $this->parent_obj = $parent_gui;
102
103 $this->lng->loadLanguageModule('search');
104 $this->lng->loadLanguageModule('obj');
105 $this->ctrl->saveParameter($this, "crtcb");
106
107 $this->clipboard = $DIC
108 ->repository()
109 ->internal()
110 ->domain()
111 ->clipboard()
112 ;
113 }
114
115 public function executeCommand(): void
116 {
117 $this->init();
118 $this->initTabs();
119
120 $this->ctrl->getNextClass($this);
121 $cmd = $this->ctrl->getCmd();
122
123 $this->$cmd();
124 }
125
126 protected function init(): void
127 {
128 if ($this->retriever->has('smode')) {
129 $this->setSubMode($this->retriever->getMaybeInt('smode') ?? 0);
130 $this->ctrl->setParameter($this, 'smode', $this->getSubMode());
131 ilLoggerFactory::getLogger('obj')->debug('Submode is: ' . $this->getSubMode());
132 }
133
134 // save sources
135 if ($this->retriever->has('source_ids')) {
136 $this->setSource(explode('_', $this->retriever->getMaybeString('source_ids')));
137 $this->ctrl->setParameter($this, 'source_ids', implode('_', $this->getSources()));
138 ilLoggerFactory::getLogger('obj')->debug('Multiple sources: ' . implode('_', $this->getSources()));
139 }
140 if ($this->retriever->has('source_id')) {
141 $this->setSource([$this->retriever->getMaybeInt('source_id')]);
142 $this->ctrl->setParameter($this, 'source_ids', implode('_', $this->getSources()));
143 ilLoggerFactory::getLogger('obj')->debug('source_id is set: ' . implode('_', $this->getSources()));
144 }
145 if ($this->getFirstSource()) {
146 $this->setType(
148 );
149 }
150
151 // creation screen: copy section
152 if ($this->retriever->has('new_type')) {
153 $this->setMode(self::SEARCH_SOURCE);
154 $this->setType($this->retriever->getMaybeString('new_type'));
155 $this->setTarget($this->request_wrapper->retrieve("ref_id", $this->refinery->kindlyTo()->int()));
156
157 $this->ctrl->setParameter($this, 'new_type', $this->getType());
158 $this->ctrl->setParameterByClass(get_class($this->getParentObject()), 'new_type', $this->getType());
159 $this->ctrl->setParameterByClass(get_class($this->getParentObject()), 'cpfl', 1);
160 $this->ctrl->setReturnByClass(get_class($this->getParentObject()), 'create');
161
162 ilLoggerFactory::getLogger('obj')->debug('Copy from object creation for type: ' . $this->getType());
163 return;
164 }
165 // adopt content, and others?
166 elseif ($this->retriever->getMaybeInt('selectMode') === self::SOURCE_SELECTION) {
167 $this->setMode(self::SOURCE_SELECTION);
168
169 $this->ctrl->setParameterByClass(get_class($this->parent_obj), 'selectMode', self::SOURCE_SELECTION);
170 $this->setTarget($this->request_wrapper->retrieve("ref_id", $this->refinery->kindlyTo()->int()));
171 $this->ctrl->setReturnByClass(get_class($this->parent_obj), '');
172
173 ilLoggerFactory::getLogger('obj')->debug('Source selection mode. Target is: ' . $this->getFirstTarget());
174 } elseif ($this->retriever->getMaybeInt('selectMode') === self::TARGET_SELECTION) {
175 $this->setMode(self::TARGET_SELECTION);
176 $this->ctrl->setReturnByClass(get_class($this->parent_obj), '');
177 ilLoggerFactory::getLogger('obj')->debug('Target selection mode.');
178 }
179
180 // save targets
181 if ($this->retriever->has('target_ids')) {
182 $this->setTargets(explode('_', $this->retriever->getMaybeString('target_ids')));
183 ilLoggerFactory::getLogger('obj')->debug('targets are: ' . print_r($this->getTargets(), true));
184 }
185 }
186
187 protected function initTabs(): void
188 {
189 $this->lng->loadLanguageModule('cntr');
190 $this->tabs->clearTargets();
191 $this->tabs->setBackTarget(
192 $this->lng->txt('tab_back_to_repository'),
193 (string) $this->ctrl->getParentReturn($this->parent_obj)
194 );
195 }
196
197 protected function setTabs(int $tab_group, int $active_tab): void
198 {
199 if ($tab_group == self::TAB_GROUP_SC_SELECTION) {
200 if ($this->getSubMode() == self::SUBMODE_CONTENT_ONLY) {
201 if ($this->getMode() == self::SOURCE_SELECTION) {
202 $this->tabs->addTab(
203 (string) self::TAB_SELECTION_SOURCE_TREE,
204 $this->lng->txt('cntr_copy_repo_tree'),
205 $this->ctrl->getLinkTarget($this, 'initSourceSelection')
206 );
207 $this->tabs->addTab(
208 (string) self::TAB_SELECTION_MEMBERSHIP,
209 $this->lng->txt('cntr_copy_crs_grp'),
210 $this->ctrl->getLinkTarget($this, 'showSourceSelectionMembership')
211 );
212 }
213 }
214 }
215 $this->tabs->activateTab((string) $active_tab);
216 }
217
221 protected function adoptContent(): void
222 {
223 $this->ctrl->setParameter($this, 'smode', self::SUBMODE_CONTENT_ONLY);
224 $this->ctrl->setParameter($this, 'selectMode', self::SOURCE_SELECTION);
225
226 $this->setSubMode(self::SUBMODE_CONTENT_ONLY);
227 $this->setMode(self::SOURCE_SELECTION);
228 $this->setTarget($this->request_wrapper->retrieve("ref_id", $this->refinery->kindlyTo()->int()));
229
230 $this->initSourceSelection();
231 }
232
236 protected function initTargetSelection(): void
237 {
238 $this->ctrl->setParameter($this, 'selectMode', self::TARGET_SELECTION);
239
240 // copy opened nodes from repository explorer
241 $node_ids = is_array(ilSession::get('repexpand')) ? ilSession::get('repexpand') : [];
242
243 // begin-patch mc
244 $this->setTargets([]);
245 // cognos-blu-patch: end
246
247 // open current position
248 foreach ($this->getSources() as $source_id) {
249 if ($source_id) {
250 $path = $this->tree->getPathId($source_id);
251 foreach ($path as $node_id) {
252 if (!in_array($node_id, $node_ids)) {
253 $node_ids[] = $node_id;
254 }
255 }
256 }
257 }
258
259 ilSession::set('paste_copy_repexpand', $node_ids);
260
261 $this->ctrl->setReturnByClass(get_class($this->parent_obj), '');
263 }
264
265 protected function initSourceSelection(): void
266 {
267 // copy opened nodes from repository explorer
268 $node_ids = is_array(ilSession::get('repexpand')) ? ilSession::get('repexpand') : [];
269
270 $this->setTabs(self::TAB_GROUP_SC_SELECTION, self::TAB_SELECTION_SOURCE_TREE);
271
272 // open current position
273 // begin-patch mc
274 foreach ($this->getTargets() as $target_ref_id) {
275 $path = $this->tree->getPathId($target_ref_id);
276 foreach ($path as $node_id) {
277 if (!in_array($node_id, $node_ids)) {
278 $node_ids[] = $node_id;
279 }
280 }
281 }
282 // end-patch multi copy
283
284 ilSession::set('paste_copy_repexpand', $node_ids);
285
286 $this->ctrl->setReturnByClass(get_class($this->parent_obj), '');
288 }
289
290
294 protected function showSourceSelectionMembership(): void
295 {
296 $this->tpl->setOnScreenMessage('info', $this->lng->txt('msg_copy_clipboard_source'));
297 $this->setTabs(self::TAB_GROUP_SC_SELECTION, self::TAB_SELECTION_MEMBERSHIP);
298
300 $this,
301 'showSourceSelectionMembership',
302 'copy_selection_mmbrs'
303 );
304 $cgs->init();
305 $cgs->setObjects(
306 array_merge(
307 ilParticipants::_getMembershipByType($this->user->getId(), ['crs']),
308 ilParticipants::_getMembershipByType($this->user->getId(), ['grp'])
309 )
310 );
311 $cgs->parse();
312
313 $this->tpl->setContent($cgs->getHTML());
314 }
315
316 public function showTargetSelectionTree(): void
317 {
318 if ($this->obj_definition->isContainer($this->getType())) {
319 $this->tpl->setOnScreenMessage('info', $this->lng->txt('msg_copy_clipboard_container'));
320 } else {
321 $this->tpl->setOnScreenMessage('info', $this->lng->txt('msg_copy_clipboard'));
322 }
323
324 $exp = new ilRepositorySelectorExplorerGUI($this, "showTargetSelectionTree");
325 $exp->setTypeWhiteList(["root", "cat", "grp", "crs", "fold", "lso", "prg"]);
326 $exp->setSelectMode("target", true);
327 if ($exp->handleCommand()) {
328 return;
329 }
330 $output = $exp->getHTML();
331
332 $t = new ilToolbarGUI();
333 $t->setFormAction($this->ctrl->getFormAction($this, "saveTarget"));
335 if ($this->obj_definition->isContainer($this->getType())) {
336 $btn->setCaption('btn_next');
337 } else {
338 $btn->setCaption('paste');
339 }
340 $btn->setCommand('saveTarget');
341 $btn->setPrimary(true);
342 $t->addButtonInstance($btn);
343 $t->addSeparator();
344 $clipboard_btn = ilSubmitButton::getInstance();
345 $clipboard_btn->setCaption('obj_insert_into_clipboard');
346 $clipboard_btn->setCommand('keepObjectsInClipboard');
347 $t->addButtonInstance($clipboard_btn);
348 $cancel_btn = ilSubmitButton::getInstance();
349 $cancel_btn->setCaption('cancel');
350 $cancel_btn->setCommand('cancel');
351 $t->addButtonInstance($cancel_btn);
352 $t->setCloseFormTag(false);
353 $t->setLeadingImage(ilUtil::getImagePath("arrow_upright.svg"), " ");
354 $output = $t->getHTML() . $output;
355 $t->setLeadingImage(ilUtil::getImagePath("arrow_downright.svg"), " ");
356 $t->setCloseFormTag(true);
357 $t->setOpenFormTag(false);
358 $output .= "<br />" . $t->getHTML();
359
360 $this->tpl->setContent($output);
361 }
362
363 public function showSourceSelectionTree(): void
364 {
365 $this->tpl->addBlockFile(
366 'ADM_CONTENT',
367 'adm_content',
368 'tpl.paste_into_multiple_objects.html',
369 "Services/Object"
370 );
371
372 $this->tpl->setOnScreenMessage('info', $this->lng->txt('msg_copy_clipboard_source'));
375 'ilias.php?baseClass=ilRepositoryGUI&amp;cmd=goto',
376 'paste_copy_repexpand'
377 );
378 $exp->setRequiredFormItemPermission('visible,read,copy');
379
380 $this->ctrl->setParameter($this, 'selectMode', self::SOURCE_SELECTION);
381 $exp->setExpandTarget($this->ctrl->getLinkTarget($this, 'showSourceSelectionTree'));
382 $exp->setTargetGet('ref_id');
383 $exp->setPostVar('source');
384 $exp->setCheckedItems($this->getSources());
385 $exp->highlightNode((string) $this->getFirstTarget());
386
387 // Filter to container
388 foreach (['cat', 'root', 'fold'] as $container) {
389 $exp->removeFormItemForType($container);
390 }
391
392 if (!$this->request_wrapper->has("paste_copy_repexpand")) {
393 $expanded = $this->tree->readRootId();
394 } else {
395 $expanded = $this->request_wrapper->retrieve("paste_copy_repexpand", $this->refinery->kindlyTo()->int());
396 }
397
398 $this->tpl->setVariable('FORM_TARGET', '_self');
399 $this->tpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this, 'copySelection'));
400
401 $exp->setExpand($expanded);
402 // build html-output
403 $exp->setOutput(0);
404 $output = $exp->getOutput();
405
406 $this->tpl->setVariable('OBJECT_TREE', $output);
407 $this->tpl->setVariable('CMD_SUBMIT', 'saveSource');
408 $this->tpl->setVariable('TXT_SUBMIT', $this->lng->txt('btn_next'));
409
410 $this->toolbar->addButton($this->lng->txt('cancel'), $this->ctrl->getLinkTarget($this, 'cancel'));
411 }
412
413 protected function saveTarget(): void
414 {
415 // begin-patch mc
416 $target = $_REQUEST['target'] ?? null; // TODO PHP8 Review: Remove/Replace SuperGlobals
417 if (is_array($target) && $target) {
418 $this->setTargets($target);
419 $this->ctrl->setParameter($this, 'target_ids', implode('_', $this->getTargets()));
420 }
421 // paste from clipboard
422 elseif ((int) $target) {
423 $this->setTarget((int) $target);
424 $this->ctrl->setParameter($this, 'target_ids', implode('_', $this->getTargets()));
425 }
426 // end-patch multi copy
427 else {
428 $this->ctrl->setParameter($this, 'selectMode', self::TARGET_SELECTION);
429 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
431 return;
432 }
433
434 // validate allowed subtypes
435 foreach ($this->getSources() as $source_ref_id) {
436 foreach ($this->getTargets() as $target_ref_id) {
437 $target_type = ilObject::_lookupType((int) $target_ref_id, true);
438 $target_class_name = ilObjectFactory::getClassByType($target_type);
439 $target_object = new $target_class_name((int) $target_ref_id);
440 $possible_subtypes = $target_object->getPossibleSubObjects();
441
442 $source_type = ilObject::_lookupType((int) $source_ref_id, true);
443
444 if (!array_key_exists($source_type, (array) $possible_subtypes)) {
445 $this->tpl->setOnScreenMessage('failure', sprintf(
446 $this->lng->txt('msg_obj_may_not_contain_objects_of_type'),
447 $this->lng->txt('obj_' . $target_type),
448 $this->lng->txt('obj_' . $source_type)
449 ));
451 return;
452 }
453 }
454 }
455
456 if (count($this->getSources()) == 1 && $this->obj_definition->isContainer($this->getType())) {
457 // check, if object should be copied into itself
458 // begin-patch mc
459 $is_child = [];
460 foreach ($this->getTargets() as $target_ref_id) {
461 if ($this->tree->isGrandChild($this->getFirstSource(), (int) $target_ref_id)) {
463 }
464 if ($this->getFirstSource() == (int) $target_ref_id) {
466 }
467 }
468 // end-patch multi copy
469 if (count($is_child) > 0) {
470 $this->tpl->setOnScreenMessage(
471 'failure',
472 $this->lng->txt("msg_not_in_itself") . " " . implode(',', $is_child)
473 );
475 return;
476 }
477
478 $this->showItemSelection();
479 } else {
480 if (count($this->getSources()) == 1) {
481 $this->copySingleObject();
482 } else {
483 $this->copyMultipleNonContainer($this->getSources());
484 }
485 }
486 }
487
488 public function setMode(int $mode): void
489 {
490 $this->mode = $mode;
491 }
492
493 public function getMode(): int
494 {
495 return $this->mode;
496 }
497
498 public function setSubMode(int $mode): void
499 {
500 $this->sub_mode = $mode;
501 }
502
503 public function getSubMode(): int
504 {
505 return $this->sub_mode;
506 }
507
511 public function getParentObject(): ?ilObjectGUI
512 {
513 return $this->parent_obj;
514 }
515
516 public function getType(): string
517 {
518 return $this->type;
519 }
520
521 public function setType(string $type): void
522 {
523 $this->type = $type;
524 }
525
526 public function setSource(array $source_ids): void
527 {
528 $this->sources = $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())->transform(
529 $source_ids
530 );
531 }
532
533 public function getSources(): array
534 {
535 return $this->sources;
536 }
537
538 public function getFirstSource(): int
539 {
540 if (count($this->sources)) {
541 return (int) $this->sources[0];
542 }
543 return 0;
544 }
545
546 // begin-patch mc
547 public function setTarget(int $ref_id): void
548 {
549 $this->setTargets([$ref_id]);
550 }
551
552 public function setTargets(array $targets): void
553 {
554 $this->targets = $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())->transform(
555 $targets
556 );
557 }
558
559 public function getTargets(): array
560 {
561 return $this->targets;
562 }
563
564 public function getFirstTarget(): int
565 {
566 if (array_key_exists(0, $this->getTargets())) {
567 $targets = $this->getTargets();
568 return (int) $targets[0];
569 }
570 return 0;
571 }
572 // end-patch multi copy
573
574 protected function cancel(): void
575 {
576 $ilCtrl = $this->ctrl;
577 $ilCtrl->setReturnByClass(get_class($this->parent_obj), 'cancel');
578 $ilCtrl->returnToParent($this);
579 }
580
581 public function keepObjectsInClipboard(): void
582 {
583 $this->tpl->setOnScreenMessage('success', $this->lng->txt("obj_inserted_clipboard"), true);
584 $ilCtrl = $this->ctrl;
585 $this->clipboard->setCmd("copy");
586 $this->clipboard->setRefIds($this->getSources());
587 $ilCtrl->returnToParent($this);
588 }
589
590 protected function searchSource(): void
591 {
592 if ($this->post_wrapper->has('tit')) {
593 $this->tpl->setOnScreenMessage('info', $this->lng->txt('wizard_search_list'));
594 ilSession::set('source_query', $this->post_wrapper->retrieve("tit", $this->refinery->kindlyTo()->string()));
595 }
596
597 $tit = ilSession::get('source_query', '');
598 if ($tit === "") {
599 $this->initFormSearch();
600 $this->form->setValuesByPost();
601
602 if (!$this->form->checkInput()) {
603 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('msg_no_search_string'), true);
604 $this->ctrl->returnToParent($this);
605 return;
606 }
607
608 $tit = $this->form->getInput('tit');
609 }
610
611 $query_parser = new ilQueryParser($tit);
612 $query_parser->setMinWordLength(1);
613 $query_parser->setCombination(ilQueryParser::QP_COMBINATION_AND);
614 $query_parser->parse();
615 if (!$query_parser->validate()) {
616 $this->tpl->setOnScreenMessage('failure', $query_parser->getMessage(), true);
617 $this->ctrl->returnToParent($this);
618 }
619
620 // only like search since fulltext does not support search with less than 3 characters
621 $object_search = new ilLikeObjectSearch($query_parser);
622 $object_search->setFilter([$this->retriever->getMaybeString('new_type')]);
623 $res = $object_search->performSearch();
624 $res->setRequiredPermission('copy');
625 $res->filter(ROOT_FOLDER_ID, true);
626
627 if (!count($results = $res->getResultsByObjId())) {
628 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('search_no_match'), true);
629 $this->ctrl->returnToParent($this);
630 }
631
632 $table = new ilObjectCopySearchResultTableGUI($this, 'searchSource', $this->getType());
633 $table->setFormAction($this->ctrl->getFormAction($this));
634 $table->setSelectedReference($this->getFirstSource());
635 $table->parseSearchResults($results);
636 $this->tpl->setContent($table->getHTML());
637 }
638
639 protected function saveSource(): void
640 {
641 if ($this->post_wrapper->has("source")) {
642 $source = $this->post_wrapper->retrieve("source", $this->refinery->kindlyTo()->int());
643 $this->setSource([$source]);
645 $this->ctrl->setParameter($this, 'source_id', $source);
646 } else {
647 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
648 $this->searchSource();
649 return;
650 }
651
652 // validate allowed subtypes
653 foreach ($this->getSources() as $source_ref_id) {
654 foreach ($this->getTargets() as $target_ref_id) {
655 $target_type = ilObject::_lookupType($target_ref_id, true);
656 $target_class_name = ilObjectFactory::getClassByType($target_type);
657 $target_object = new $target_class_name($target_ref_id);
658 $possible_subtypes = $target_object->getPossibleSubObjects();
659
660 $source_type = ilObject::_lookupType($source_ref_id, true);
661
662 if (!array_key_exists($source_type, $possible_subtypes)) {
663 // adopt content mode
664 if (
665 $this->getSubMode() != self::SUBMODE_CONTENT_ONLY and
666 ($source_type != 'crs' or $target_type != 'crs')
667 ) {
668 $this->tpl->setOnScreenMessage('failure', sprintf(
669 $this->lng->txt('msg_obj_may_not_contain_objects_of_type'),
670 $this->lng->txt('obj_' . $target_type),
671 $this->lng->txt('obj_' . $source_type)
672 ));
673 $this->searchSource();
674 return;
675 }
676 }
677 }
678 }
679
680 if ($this->obj_definition->isContainer($this->getType())) {
681 $this->showItemSelection();
682 return;
683 }
684
685 $this->copySingleObject();
686 }
687
691 protected function saveSourceMembership(): void
692 {
693 $source = $this->retriever->getMaybeInt('source');
694 if ($source === null) {
695 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
696 $this->ctrl->redirect($this, 'showSourceSelectionMembership');
697 return;
698 }
699
700 $this->setSource([$source]);
701 $this->setType(ilObject::_lookupType($this->getFirstSource(), true));
702 $this->ctrl->setParameter($this, 'source_id', $source);
703
704 if ($this->obj_definition->isContainer($this->getType())) {
705 $this->showItemSelection();
706 return;
707 }
708
709 $this->copySingleObject();
710 }
711
712 protected function showItemSelection(): void
713 {
714 if (!count($this->getSources())) {
715 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'));
716 $this->searchSource();
717 return;
718 }
719
720 $this->log->debug('Source(s): ' . print_r($this->getSources(), true));
721 $this->log->debug('Target(s): ' . print_r($this->getTargets(), true));
722
723 $this->tpl->setOnScreenMessage('info', $this->lng->txt($this->getType() . '_copy_threads_info'));
724 $this->tpl->addJavaScript('./Services/CopyWizard/js/ilContainer.js');
725 $this->tpl->setVariable('BODY_ATTRIBUTES', 'onload="ilDisableChilds(\'cmd\');"');
726
727 $back_cmd = "";
728 switch ($this->getMode()) {
730 $back_cmd = 'adoptContent';
731 break;
732
734 $back_cmd = 'showTargetSelectionTree';
735 break;
736
738 $back_cmd = 'searchSource';
739 break;
740 }
741
742 $table = new ilObjectCopySelectionTableGUI($this, 'showItemSelection', $this->getType(), $back_cmd);
743 $table->parseSource($this->getFirstSource());
744
745 $this->tpl->setContent($table->getHTML());
746 }
747
751 protected function copySingleObject(): void
752 {
753 // Source defined
754 if (!count($this->getSources())) {
755 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
756 $this->ctrl->returnToParent($this);
757 }
758
759 $this->copyMultipleNonContainer($this->getSources());
760 }
761
767 public function copyMultipleNonContainer(array $sources): void
768 {
769 // check permissions
770 foreach ($sources as $source_ref_id) {
771 $source_type = ilObject::_lookupType($source_ref_id, true);
772
773 // Create permission
774 // begin-patch mc
775 foreach ($this->getTargets() as $target_ref_id) {
776 if (!$this->rbacsystem->checkAccess('create', $target_ref_id, $source_type)) {
777 $this->log->notice(
778 'Permission denied for target_id: ' .
779 $target_ref_id .
780 ' source_type: ' .
781 $source_type .
782 ' CREATE'
783 );
784 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true);
785 $this->ctrl->returnToParent($this);
786 }
787 }
788
789 // Copy permission
790 if (!$this->access->checkAccess('copy', '', $source_ref_id)) {
791 $this->log->notice('Permission denied for source_ref_id: ' . $source_ref_id . ' COPY');
792 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true);
793 $this->ctrl->returnToParent($this);
794 }
795
796 // check that these objects are really not containers
797 if ($this->obj_definition->isContainer($source_type) and $this->getSubMode() != self::SUBMODE_CONTENT_ONLY) {
798 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('cntr_container_only_on_their_own'), true);
799 $this->ctrl->returnToParent($this);
800 }
801 }
802
803 reset($sources);
804
805
806 ilLoggerFactory::getLogger('obj')->debug('Copy multiple non containers. Sources: ' . print_r($sources, true));
807
808 $new_obj = null;
809 // clone
810 foreach ($sources as $source_ref_id) {
811 ilLoggerFactory::getLogger('obj')->debug('Copying source ref_id : ' . $source_ref_id);
812
813 // begin-patch mc
814 foreach ($this->getTargets() as $target_ref_id) {
815 // Save wizard options
817 $wizard_options = ilCopyWizardOptions::_getInstance($copy_id);
818 $wizard_options->saveOwner($this->user->getId());
819 $wizard_options->saveRoot((int) $source_ref_id);
820 $wizard_options->read();
821
822 $orig = ilObjectFactory::getInstanceByRefId((int) $source_ref_id);
823 $new_obj = $orig->cloneObject($target_ref_id, $copy_id);
824
825 // Delete wizard options
826 $wizard_options->deleteAll();
827 $this->parent_obj->callCreationCallback(
828 $new_obj,
829 $this->obj_definition,
830 $this->retriever->getMaybeInt('crtcb', 0)
831 );
832
833 // rbac log
834 if (ilRbacLog::isActive()) {
835 $rbac_log_roles = $this->rbacreview->getParentRoleIds($new_obj->getRefId());
836 $rbac_log = ilRbacLog::gatherFaPa($new_obj->getRefId(), array_keys($rbac_log_roles), true);
837 ilRbacLog::add(ilRbacLog::COPY_OBJECT, $new_obj->getRefId(), $rbac_log, (bool) $source_ref_id);
838 }
839 }
840 }
841
842 $this->clipboard->clear();
843 $this->log->info('Object copy completed.');
844 if (count($sources) == 1) {
845 $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_duplicated"), true);
846 $ref_id = $new_obj->getRefId();
847 } else {
848 $this->tpl->setOnScreenMessage('success', $this->lng->txt("objects_duplicated"), true);
849 $ref_id = $this->getFirstTarget();
850 }
851
852 $this->tpl->setOnScreenMessage('success', $this->lng->txt("objects_duplicated"), true);
854 }
855
856 protected function copyContainerToTargets(): void
857 {
858 $this->log->debug('Copy container to targets: ' . print_r($_REQUEST, true));
859 $this->log->debug('Source(s): ' . print_r($this->getSources(), true));
860 $this->log->debug('Target(s): ' . print_r($this->getTargets(), true));
861
862 $result = 1;
863 foreach ($this->getTargets() as $target_ref_id) {
864 $result = $this->copyContainer((int) $target_ref_id);
865 }
866
867 $this->clipboard->clear();
868
869 if (ilCopyWizardOptions::_isFinished($result['copy_id'])) {
870 $this->log->info('Object copy completed.');
871 $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_duplicated"), true);
872 if ($this->getSubMode() == self::SUBMODE_CONTENT_ONLY) {
873 $this->ctrl->returnToParent($this);
874 }
875 $link = ilLink::_getLink($result['ref_id']);
876 $this->ctrl->redirectToURL($link);
877 } else {
878 $this->log->debug('Object copy in progress.');
879 $this->showCopyProgress();
880 }
881 }
882
883 protected function showCopyProgress(): void
884 {
886 if ($this->request_wrapper->has('ref_id')) {
887 $ref_id = $this->request_wrapper->retrieve(
888 'ref_id',
889 $this->refinery->kindlyTo()->int()
890 );
891 }
892
893 $progress = new ilObjectCopyProgressTableGUI(
894 $this,
895 'showCopyProgress',
896 $ref_id
897 );
898 $progress->setObjectInfo($this->targets_copy_id);
899 $progress->parse();
900 $progress->init();
901 $link = ilLink::_getLink($ref_id);
902 $progress->setRedirectionUrl($link);
903
904 $this->tpl->setContent($progress->getHTML());
905 }
906
907 protected function updateProgress(): void
908 {
909 $json = new stdClass();
910 $json->percentage = null;
911 $json->performed_steps = null;
912
913 $copy_id = $this->retriever->getMaybeInt('_copy_id');
914 $options = ilCopyWizardOptions::_getInstance($copy_id);
915 $node = $options->fetchFirstNode();
916 $json->current_node_id = 0;
917 $json->current_node_title = "";
918 $json->in_dependencies = false;
919 if (is_array($node)) {
920 $json->current_node_id = $node['obj_id'];
921 $json->current_node_title = $node['title'];
922 } else {
923 $node = $options->fetchFirstDependenciesNode();
924 if (is_array($node)) {
925 $json->current_node_id = $node['obj_id'];
926 $json->current_node_title = $node['title'];
927 $json->in_dependencies = true;
928 }
929 }
930 $json->required_steps = $options->getRequiredSteps();
931 $json->id = $copy_id;
932
933 $this->log->debug('Update copy progress: ' . json_encode($json));
934
935 echo json_encode($json);
936 exit;
937 }
938
939 protected function copyContainer(int $target_ref_id): array
940 {
941 if ($this->getSubMode() != self::SUBMODE_CONTENT_ONLY) {
942 if (!$this->rbacsystem->checkAccess('create', $target_ref_id, $this->getType())) {
943 $this->log->notice(
944 'Permission denied for target: ' .
945 $target_ref_id .
946 ' type: ' .
947 $this->getType() .
948 ' CREATE'
949 );
950 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true);
951 $this->ctrl->returnToParent($this);
952 }
953 }
954
955 if (!$this->getFirstSource()) {
956 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
957 $this->ctrl->returnToParent($this);
958 }
959
960 $options = [];
961 if ($this->post_wrapper->has("cp_options")) {
962 $options = $this->post_wrapper->retrieve(
963 "cp_options",
964 $this->refinery->kindlyTo()->dictOf(
965 $this->refinery->kindlyTo()->dictOf($this->refinery->kindlyTo()->string())
966 )
967 );
968 }
969
970 $this->log->debug('Copy container (sources): ' . print_r($this->getSources(), true));
971
973 $result = $orig->cloneAllObject(
974 $_COOKIE[session_name()],
975 CLIENT_ID,
976 $this->getType(),
977 $target_ref_id,
978 $this->getFirstSource(),
979 $options,
980 false,
981 $this->getSubMode()
982 );
983
984 $this->targets_copy_id[$target_ref_id] = $result['copy_id'];
985
986 $new_ref_id = (int) $result['ref_id'];
987 if ($new_ref_id > 0) {
988 $new_obj = ilObjectFactory::getInstanceByRefId((int) $result['ref_id'], false);
989 if ($new_obj instanceof ilObject) {
990 $this->parent_obj->callCreationCallback(
991 $new_obj,
992 $this->obj_definition,
993 $this->retriever->getMaybeInt('crtcb', 0)
994 );
995 }
996 }
997 return $result;
998 }
999
1006 public function showSourceSearch(?string $tpl_var): ?ilPropertyFormGUI
1007 {
1008 $this->unsetSession();
1009 $this->initFormSearch();
1010
1011 if ($tpl_var) {
1012 $this->tpl->setVariable($tpl_var, $this->form->getHTML());
1013 return null;
1014 }
1015
1016 return $this->form;
1017 }
1018
1022 protected function sourceExists(): bool
1023 {
1024 return (bool) ilUtil::_getObjectsByOperations($this->getType(), 'copy', $this->user->getId(), 1);
1025 }
1026
1027 protected function initFormSearch(): void
1028 {
1029 $this->form = new ilPropertyFormGUI();
1030 $this->form->setTableWidth('600px');
1031 $this->ctrl->setParameter($this, 'new_type', $this->getType());
1032 $this->form->setFormAction($this->ctrl->getFormAction($this));
1033 $this->form->setTitle($this->lng->txt($this->getType() . '_copy'));
1034 $this->form->addCommandButton('searchSource', $this->lng->txt('search_for'));
1035 $this->form->addCommandButton('cancel', $this->lng->txt('cancel'));
1036
1037 $tit = new ilTextInputGUI($this->lng->txt('title'), 'tit');
1038 $tit->setSize(40);
1039 $tit->setMaxLength(70);
1040 $tit->setRequired(true);
1041 $tit->setInfo($this->lng->txt('wizard_title_info'));
1042 $this->form->addItem($tit);
1043 }
1044
1048 protected function unsetSession(): void
1049 {
1050 ilSession::clear('source_query');
1051 $this->setSource([]);
1052 }
1053}
Builds data types.
Definition: Factory.php:21
Manages items in repository clipboard.
error(string $a_errmsg)
static _allocateCopyId()
Allocate a copy for further entries.
static _isFinished(int $a_copy_id)
static _getInstance(int $a_copy_id)
Class ilCtrl provides processing control methods.
setCmd(?string $a_cmd)
@inheritDoc
setReturnByClass(string $a_class, string $a_cmd=null)
@inheritDoc
Error Handling & global info handling uses PEAR error class.
language handling
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
User class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
GUI class for the workflow of copying objects.
ilPropertyFormGUI $form
sourceExists()
Check if there is any source object.
unsetSession()
Unset session variables.
copyMultipleNonContainer(array $sources)
Copy multiple non container.
ILIAS HTTP Wrapper ArrayBasedRequestWrapper $post_wrapper
ilErrorHandling $error
setTabs(int $tab_group, int $active_tab)
ilObjectDefinition $obj_definition
initTargetSelection()
Init copy from repository/search list commands.
ilObjectRequestRetriever $retriever
setSource(array $source_ids)
ILIAS HTTP Wrapper RequestWrapper $request_wrapper
ILIAS Refinery Factory $refinery
ilObjectDataCache $obj_data_cache
getParentObject()
Get parent gui object.
copySingleObject()
Start cloning a single (not container) object.
ilGlobalTemplateInterface $tpl
saveSourceMembership()
Save selected source from membership screen.
ClipboardManager $clipboard
ImplementsCreationCallback $parent_obj
copyContainer(int $target_ref_id)
ilAccessHandler $access
showSourceSearch(?string $tpl_var)
Show init screen Normally shown below the create and import form when creating a new object.
adoptContent()
Adopt content (crs in crs, grp in grp, crs in grp or grp in crs)
showSourceSelectionMembership()
show target selection membership
__construct(ImplementsCreationCallback $parent_gui)
setTargets(array $targets)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
parses the objects.xml it handles the xml-description of all ilias objects
static getClassByType(string $obj_type)
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
Class ilObjectGUI Basic methods of all Output classes.
Base class for all sub item list gui's.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $id, bool $reference=false)
static _lookupObjId(int $ref_id)
static _lookupTitle(int $obj_id)
static _getMembershipByType(int $a_usr_id, array $a_type, bool $a_only_member_role=false)
get membership by type Get course or group membership
ilPasteIntoMultipleItemsExplorer Explorer
This class represents a property form user interface.
const COPY_OBJECT
static add(int $a_action, int $a_ref_id, array $a_diff, bool $a_source_ref_id=false)
static gatherFaPa(int $a_ref_id, array $a_role_ids, bool $a_add_action=false)
static isActive()
class ilRbacReview Contains Review functions of core Rbac.
class ilRbacSystem system function like checkAccess, addActiveRole ... Supporting system functions ar...
Explorer for selecting repository items.
static get(string $a_var)
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a text property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static redirect(string $a_script)
static _getObjectsByOperations( $a_obj_type, string $a_operation, int $a_usr_id=0, int $limit=0)
Get all objects of a specific type and check access This function is not recursive,...
const CLIENT_ID
Definition: constants.php:41
const ROOT_FOLDER_ID
Definition: constants.php:32
global $DIC
Definition: feed.php:28
$target_type
Definition: goto.php:51
Interface RequestWrapper.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
exit
Definition: login.php:28
$ref_id
Definition: ltiauth.php:67
$path
Definition: ltiservices.php:32
$res
Definition: ltiservices.php:69
$source
Definition: metadata.php:93
form( $class_path, string $cmd)
$results
$container
@noRector
Definition: wac.php:14
$_COOKIE[session_name()]
Definition: xapitoken.php:54