1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4/** 5 * GUI class for the workflow of copying objects 6 * 7 * @author Stefan Meyer <smeyer.ilias@gmx.de> 8 * @author Stefan Hecken <stefan.hecken@concepts-and-training.de> 9 * @version $Id$ 10 * 11 * @ilCtrl_Calls ilObjectCopyGUI: 12 * 13 * @ingroup ServicesObject 14 */ 15class ilObjectCopyGUI 16{ 17 /** 18 * @var ilCtrl 19 */ 20 protected $ctrl; 21 22 /** 23 * @var ilTree 24 */ 25 protected $tree; 26 27 /** 28 * @var ilTabsGUI 29 */ 30 protected $tabs; 31 32 /** 33 * @var ilToolbarGUI 34 */ 35 protected $toolbar; 36 37 /** 38 * @var ilTemplate 39 */ 40 protected $tpl; 41 42 /** 43 * @var ilObjectDefinition 44 */ 45 protected $obj_definition; 46 47 /** 48 * @var ilObjectDataCache 49 */ 50 protected $obj_data_cache; 51 52 /** 53 * @var ilAccessHandler 54 */ 55 protected $access; 56 57 /** 58 * @var ilErrorHandling 59 */ 60 protected $error; 61 62 /** 63 * @var ilRbacSystem 64 */ 65 protected $rbacsystem; 66 67 /** 68 * @var ilObjUser 69 */ 70 protected $user; 71 72 /** 73 * @var ilRbacReview 74 */ 75 protected $rbacreview; 76 77 const SOURCE_SELECTION = 1; 78 const TARGET_SELECTION = 2; 79 const SEARCH_SOURCE = 3; 80 81 const SUBMODE_COMPLETE = 1; 82 const SUBMODE_CONTENT_ONLY = 2; 83 84 // tabs 85 const TAB_SELECTION_TARGET_TREE = 1; 86 const TAB_SELECTION_SOURCE_TREE = 2; 87 const TAB_SELECTION_MEMBERSHIP = 3; 88 89 // group selection of source or target 90 const TAB_GROUP_SC_SELECTION = 1; 91 92 93 private $mode = 0; 94 private $sub_mode = self::SUBMODE_COMPLETE; 95 96 private $lng; 97 98 private $parent_obj = null; 99 100 private $type = ''; 101 102 private $sources = array(); 103 104 // begin-patch multi copy 105 private $targets = array(); 106 private $targets_copy_id = array(); 107 // end-patch multi copy 108 109 /** 110 * @var ilLogger 111 */ 112 private $log = null; 113 114 115 /** 116 * Constructor 117 * @return 118 */ 119 public function __construct($a_parent_gui) 120 { 121 global $DIC; 122 123 $this->ctrl = $DIC->ctrl(); 124 $this->tree = $DIC->repositoryTree(); 125 $this->tabs = $DIC->tabs(); 126 $this->toolbar = $DIC->toolbar(); 127 $this->tpl = $DIC["tpl"]; 128 $this->obj_definition = $DIC["objDefinition"]; 129 $this->obj_data_cache = $DIC["ilObjDataCache"]; 130 $this->access = $DIC->access(); 131 $this->error = $DIC["ilErr"]; 132 $this->rbacsystem = $DIC->rbac()->system(); 133 $this->user = $DIC->user(); 134 $this->rbacreview = $DIC->rbac()->review(); 135 $this->log = $DIC["ilLog"]; 136 $ilCtrl = $DIC->ctrl(); 137 $lng = $DIC->language(); 138 139 $this->lng = $lng; 140 $this->lng->loadLanguageModule('search'); 141 $this->lng->loadLanguageModule('obj'); 142 143 $this->parent_obj = $a_parent_gui; 144 145 $this->log = ilLoggerFactory::getLogger('obj'); 146 } 147 148 /** 149 * Control class handling 150 * @return 151 */ 152 public function executeCommand() 153 { 154 $ilCtrl = $this->ctrl; 155 156 $this->init(); 157 $this->initTabs(); 158 159 $next_class = $ilCtrl->getNextClass($this); 160 $cmd = $ilCtrl->getCmd(); 161 162 switch ($next_class) { 163 default: 164 $this->$cmd(); 165 break; 166 } 167 } 168 169 /** 170 * Init return, mode 171 * @return 172 */ 173 protected function init() 174 { 175 $ilCtrl = $this->ctrl; 176 177 if ((int) $_REQUEST['smode']) { 178 $this->setSubMode((int) $_REQUEST['smode']); 179 $ilCtrl->setParameter($this, 'smode', $this->getSubMode()); 180 ilLoggerFactory::getLogger('obj')->debug('Submode is: ' . $this->getSubMode()); 181 } 182 183 // save sources 184 if ($_REQUEST['source_ids']) { 185 $this->setSource(explode('_', $_REQUEST['source_ids'])); 186 $ilCtrl->setParameter($this, 'source_ids', implode('_', $this->getSources())); 187 ilLoggerFactory::getLogger('obj')->debug('Multiple sources: ' . implode('_', $this->getSources())); 188 } 189 if ($_REQUEST['source_id']) { 190 $this->setSource(array((int) $_REQUEST['source_id'])); 191 $ilCtrl->setParameter($this, 'source_ids', implode('_', $this->getSources())); 192 ilLoggerFactory::getLogger('obj')->debug('source_id is set: ' . implode('_', $this->getSources())); 193 } 194 if ($this->getFirstSource()) { 195 $this->setType( 196 ilObject::_lookupType(ilObject::_lookupObjId($this->getFirstSource())) 197 ); 198 } 199 200 // creation screen: copy section 201 if ($_REQUEST['new_type']) { 202 $this->setMode(self::SEARCH_SOURCE); 203 $this->setType($_REQUEST['new_type']); 204 $this->setTarget((int) $_GET['ref_id']); 205 206 $ilCtrl->setParameter($this, 'new_type', $this->getType()); 207 $ilCtrl->setParameterByClass(get_class($this->getParentObject()), 'new_type', $this->getType()); 208 $ilCtrl->setParameterByClass(get_class($this->getParentObject()), 'cpfl', 1); 209 $ilCtrl->setReturnByClass(get_class($this->getParentObject()), 'create'); 210 211 ilLoggerFactory::getLogger('obj')->debug('Copy from object creation for type: ' . $this->getType()); 212 return true; 213 } 214 // adopt content, and others? 215 elseif ($_REQUEST['selectMode'] == self::SOURCE_SELECTION) { 216 $this->setMode(self::SOURCE_SELECTION); 217 218 $ilCtrl->setParameterByClass(get_class($this->parent_obj), 'selectMode', self::SOURCE_SELECTION); 219 $this->setTarget((int) $_GET['ref_id']); 220 $ilCtrl->setReturnByClass(get_class($this->parent_obj), ''); 221 222 ilLoggerFactory::getLogger('obj')->debug('Source selection mode. Target is: ' . $this->getFirstTarget()); 223 } elseif ($_REQUEST['selectMode'] == self::TARGET_SELECTION) { 224 $this->setMode(self::TARGET_SELECTION); 225 $ilCtrl->setReturnByClass(get_class($this->parent_obj), ''); 226 ilLoggerFactory::getLogger('obj')->debug('Target selection mode.'); 227 } 228 229 230 // save targets 231 if ($_REQUEST['target_ids']) { 232 $this->setTargets(explode('_', $_REQUEST['target_ids'])); 233 ilLoggerFactory::getLogger('obj')->debug('targets are: ' . print_r($this->getTargets(), true)); 234 } 235 } 236 237 /** 238 * Init tabs 239 * General 240 */ 241 protected function initTabs() 242 { 243 $lng = $this->lng; 244 $ilTabs = $this->tabs; 245 $ilCtrl = $this->ctrl; 246 247 $lng->loadLanguageModule('cntr'); 248 $ilTabs->clearTargets(); 249 $ilTabs->setBackTarget( 250 $lng->txt('tab_back_to_repository'), 251 $ilCtrl->getParentReturn($this->parent_obj) 252 ); 253 } 254 255 /** 256 * Set tabs 257 * @param type $a_tab_group 258 * @param type $a_active_tab 259 */ 260 protected function setTabs($a_tab_group, $a_active_tab) 261 { 262 $lng = $this->lng; 263 $ilTabs = $this->tabs; 264 $ilCtrl = $this->ctrl; 265 266 if ($a_tab_group == self::TAB_GROUP_SC_SELECTION) { 267 if ($this->getSubMode() == self::SUBMODE_CONTENT_ONLY) { 268 if ($this->getMode() == self::SOURCE_SELECTION) { 269 $ilTabs->addTab( 270 self::TAB_SELECTION_SOURCE_TREE, 271 $lng->txt('cntr_copy_repo_tree'), 272 $ilCtrl->getLinkTarget($this, 'initSourceSelection') 273 ); 274 $ilTabs->addTab( 275 self::TAB_SELECTION_MEMBERSHIP, 276 $lng->txt('cntr_copy_crs_grp'), 277 $ilCtrl->getLinkTarget($this, 'showSourceSelectionMembership') 278 ); 279 } 280 } 281 } 282 $ilTabs->activateTab($a_active_tab); 283 } 284 285 286 /** 287 * Adopt content (crs in crs, grp in grp, crs in grp or grp in crs) 288 * @return type 289 */ 290 protected function adoptContent() 291 { 292 $ilCtrl = $this->ctrl; 293 294 $ilCtrl->setParameter($this, 'smode', self::SUBMODE_CONTENT_ONLY); 295 $ilCtrl->setParameter($this, 'selectMode', self::SOURCE_SELECTION); 296 297 298 $this->setSubMode(self::SUBMODE_CONTENT_ONLY); 299 $this->setMode(self::SOURCE_SELECTION); 300 $this->setTarget((int) $_GET['ref_id']); 301 302 303 return $this->initSourceSelection(); 304 } 305 306 /** 307 * Init copy from repository/search list commands 308 * @return 309 */ 310 protected function initTargetSelection() 311 { 312 $ilCtrl = $this->ctrl; 313 $tree = $this->tree; 314 $ilCtrl->setParameter($this, 'selectMode', self::TARGET_SELECTION); 315 // empty session on init 316 $_SESSION['paste_copy_repexpand'] = array(); 317 318 // copy opened nodes from repository explorer 319 $_SESSION['paste_copy_repexpand'] = is_array($_SESSION['repexpand']) ? $_SESSION['repexpand'] : array(); 320 321 // begin-patch mc 322 $this->setTargets(array()); 323 // cognos-blu-patch: end 324 325 // open current position 326 327 foreach ($this->getSources() as $source_id) { 328 if ($source_id) { 329 $path = $tree->getPathId($source_id); 330 foreach ((array) $path as $node_id) { 331 if (!in_array($node_id, $_SESSION['paste_copy_repexpand'])) { 332 $_SESSION['paste_copy_repexpand'][] = $node_id; 333 } 334 } 335 } 336 } 337 338 $ilCtrl->setReturnByClass(get_class($this->parent_obj), ''); 339 $this->showTargetSelectionTree(); 340 } 341 342 /** 343 * Init source selection 344 * @return 345 */ 346 protected function initSourceSelection() 347 { 348 $ilCtrl = $this->ctrl; 349 $tree = $this->tree; 350 351 // empty session on init 352 $_SESSION['paste_copy_repexpand'] = array(); 353 354 // copy opened nodes from repository explorer 355 $_SESSION['paste_copy_repexpand'] = is_array($_SESSION['repexpand']) ? $_SESSION['repexpand'] : array(); 356 357 $this->setTabs(self::TAB_GROUP_SC_SELECTION, self::TAB_SELECTION_SOURCE_TREE); 358 359 360 // open current position 361 // begin-patch mc 362 foreach ($this->getTargets() as $target_ref_id) { 363 $path = $tree->getPathId($target_ref_id); 364 foreach ((array) $path as $node_id) { 365 if (!in_array($node_id, $_SESSION['paste_copy_repexpand'])) { 366 $_SESSION['paste_copy_repexpand'][] = $node_id; 367 } 368 } 369 } 370 // end-patch multi copy 371 $ilCtrl->setReturnByClass(get_class($this->parent_obj), ''); 372 $this->showSourceSelectionTree(); 373 } 374 375 376 /** 377 * show target selection membership 378 */ 379 protected function showSourceSelectionMembership() 380 { 381 $user = $this->user; 382 $tpl = $this->tpl; 383 384 ilUtil::sendInfo($this->lng->txt('msg_copy_clipboard_source')); 385 $this->setTabs(self::TAB_GROUP_SC_SELECTION, self::TAB_SELECTION_MEMBERSHIP); 386 387 include_once './Services/Object/classes/class.ilObjectCopyCourseGroupSelectionTableGUI.php'; 388 $cgs = new ilObjectCopyCourseGroupSelectionTableGUI($this, 'showSourceSelectionMembership', 'copy_selection_membership'); 389 $cgs->init(); 390 $cgs->setObjects( 391 array_merge( 392 ilParticipants::_getMembershipByType($user->getId(), 'crs', false), 393 ilParticipants::_getMembershipByType($user->getId(), 'grp', false) 394 ) 395 ); 396 $cgs->parse(); 397 398 $tpl->setContent($cgs->getHTML()); 399 } 400 401 402 /** 403 * Show target selection 404 */ 405 public function showTargetSelectionTree() 406 { 407 $ilTabs = $this->tabs; 408 $ilToolbar = $this->toolbar; 409 $ilCtrl = $this->ctrl; 410 $tree = $this->tree; 411 $tpl = $this->tpl; 412 $objDefinition = $this->obj_definition; 413 $lng = $this->lng; 414 415 $this->tpl = $tpl; 416 417 if ($objDefinition->isContainer($this->getType())) { 418 ilUtil::sendInfo($this->lng->txt('msg_copy_clipboard_container')); 419 } else { 420 ilUtil::sendInfo($this->lng->txt('msg_copy_clipboard')); 421 } 422 423 // 424 include_once("./Services/Repository/classes/class.ilRepositorySelectorExplorerGUI.php"); 425 $exp = new ilRepositorySelectorExplorerGUI($this, "showTargetSelectionTree"); 426 $exp->setTypeWhiteList(array("root", "cat", "grp", "crs", "fold", "lso", "prg")); 427 $exp->setSelectMode("target", true); 428 if ($exp->handleCommand()) { 429 return; 430 } 431 $output = $exp->getHTML(); 432 433 // toolbars 434 $t = new ilToolbarGUI(); 435 $t->setFormAction($ilCtrl->getFormAction($this, "saveTarget")); 436 if ($objDefinition->isContainer($this->getType())) { 437 $btn = ilSubmitButton::getInstance(); 438 $btn->setCaption('btn_next'); 439 $btn->setCommand('saveTarget'); 440 $btn->setPrimary(true); 441 $t->addButtonInstance($btn); 442 } else { 443 $btn = ilSubmitButton::getInstance(); 444 $btn->setCaption('paste'); 445 $btn->setCommand('saveTarget'); 446 $btn->setPrimary(true); 447 $t->addButtonInstance($btn); 448 } 449 $t->addSeparator(); 450 $clipboard_btn = ilSubmitButton::getInstance(); 451 $clipboard_btn->setCaption('obj_insert_into_clipboard'); 452 $clipboard_btn->setCommand('keepObjectsInClipboard'); 453 $t->addButtonInstance($clipboard_btn); 454 $cancel_btn = ilSubmitButton::getInstance(); 455 $cancel_btn->setCaption('cancel'); 456 $cancel_btn->setCommand('cancel'); 457 $t->addButtonInstance($cancel_btn); 458 $t->setCloseFormTag(false); 459 $t->setLeadingImage(ilUtil::getImagePath("arrow_upright.svg"), " "); 460 $output = $t->getHTML() . $output; 461 $t->setLeadingImage(ilUtil::getImagePath("arrow_downright.svg"), " "); 462 $t->setCloseFormTag(true); 463 $t->setOpenFormTag(false); 464 $output .= "<br />" . $t->getHTML(); 465 466 $this->tpl->setContent($output); 467 468 return; 469 } 470 471 /** 472 * Show target selection 473 */ 474 public function showSourceSelectionTree() 475 { 476 $ilTabs = $this->tabs; 477 $ilToolbar = $this->toolbar; 478 $ilCtrl = $this->ctrl; 479 $tree = $this->tree; 480 $tpl = $this->tpl; 481 $objDefinition = $this->obj_definition; 482 483 $this->tpl = $tpl; 484 $this->tpl->addBlockfile( 485 'ADM_CONTENT', 486 'adm_content', 487 'tpl.paste_into_multiple_objects.html', 488 "Services/Object" 489 ); 490 491 ilUtil::sendInfo($this->lng->txt('msg_copy_clipboard_source')); 492 include_once './Services/Object/classes/class.ilPasteIntoMultipleItemsExplorer.php'; 493 $exp = new ilPasteIntoMultipleItemsExplorer( 494 ilPasteIntoMultipleItemsExplorer::SEL_TYPE_RADIO, 495 'ilias.php?baseClass=ilRepositoryGUI&cmd=goto', 496 'paste_copy_repexpand' 497 ); 498 $exp->setRequiredFormItemPermission('visible,read,copy'); 499 500 $ilCtrl->setParameter($this, 'selectMode', self::SOURCE_SELECTION); 501 $exp->setExpandTarget($ilCtrl->getLinkTarget($this, 'showSourceSelectionTree')); 502 $exp->setTargetGet('ref_id'); 503 $exp->setPostVar('source'); 504 $exp->setCheckedItems($this->getSources()); 505 506 // Filter to container 507 foreach (array('cat','root','fold') as $container) { 508 $exp->removeFormItemForType($container); 509 } 510 511 512 if ($_GET['paste_copy_repexpand'] == '') { 513 $expanded = $tree->readRootId(); 514 } else { 515 $expanded = $_GET['paste_copy_repexpand']; 516 } 517 518 $this->tpl->setVariable('FORM_TARGET', '_self'); 519 $this->tpl->setVariable('FORM_ACTION', $ilCtrl->getFormAction($this, 'copySelection')); 520 521 $exp->setExpand($expanded); 522 // build html-output 523 $exp->setOutput(0); 524 $output = $exp->getOutput(); 525 526 $this->tpl->setVariable('OBJECT_TREE', $output); 527 528 $this->tpl->setVariable('CMD_SUBMIT', 'saveSource'); 529 $this->tpl->setVariable('TXT_SUBMIT', $this->lng->txt('btn_next')); 530 531 $ilToolbar->addButton($this->lng->txt('cancel'), $ilCtrl->getLinkTarget($this, 'cancel')); 532 } 533 534 /** 535 * Save target selection 536 * @return 537 */ 538 protected function saveTarget() 539 { 540 $objDefinition = $this->obj_definition; 541 $tree = $this->tree; 542 $ilCtrl = $this->ctrl; 543 544 545 // begin-patch mc 546 if (is_array($_REQUEST['target']) and $_REQUEST['target']) { 547 $this->setTargets($_REQUEST['target']); 548 $ilCtrl->setParameter($this, 'target_ids', implode('_', $this->getTargets())); 549 } 550 // paste from clipboard 551 elseif ((int) $_REQUEST['target']) { 552 $this->setTarget($_REQUEST['target']); 553 $ilCtrl->setParameter($this, 'target_ids', implode('_', $this->getTargets())); 554 } 555 // end-patch multi copy 556 else { 557 $ilCtrl->setParameter($this, 'selectMode', self::TARGET_SELECTION); 558 ilUtil::sendFailure($this->lng->txt('select_one')); 559 $this->showTargetSelectionTree(); 560 return false; 561 } 562 563 // validate allowed subtypes 564 foreach ($this->getSources() as $source_ref_id) { 565 foreach ((array) $this->getTargets() as $target_ref_id) { 566 $target_type = ilObject::_lookupType($target_ref_id, true); 567 $target_class_name = ilObjectFactory::getClassByType($target_type); 568 $target_object = new $target_class_name($target_ref_id); 569 $possible_subtypes = $target_object->getPossibleSubObjects(); 570 571 $source_type = ilObject::_lookupType($source_ref_id, true); 572 573 if (!array_key_exists($source_type, (array) $possible_subtypes)) { 574 ilUtil::sendFailure( 575 sprintf( 576 $this->lng->txt('msg_obj_may_not_contain_objects_of_type'), 577 $this->lng->txt('obj_' . $target_type), 578 $this->lng->txt('obj_' . $source_type) 579 ) 580 ); 581 $this->showTargetSelectionTree(); 582 return false; 583 } 584 } 585 } 586 587 if (count($this->getSources()) == 1 && $objDefinition->isContainer($this->getType())) { 588 // check, if object should be copied into itself 589 // begin-patch mc 590 $is_child = array(); 591 foreach ($this->getTargets() as $target_ref_id) { 592 if ($tree->isGrandChild($this->getFirstSource(), $target_ref_id)) { 593 $is_child[] = ilObject::_lookupTitle(ilObject::_lookupObjId($this->getFirstSource())); 594 } 595 if ($this->getFirstSource() == $target_ref_id) { 596 $is_child[] = ilObject::_lookupTitle(ilObject::_lookupObjId($this->getFirstSource())); 597 } 598 } 599 // end-patch multi copy 600 if (count($is_child) > 0) { 601 ilUtil::sendFailure($this->lng->txt("msg_not_in_itself") . " " . implode(',', $is_child)); 602 $this->showTargetSelectionTree(); 603 return false; 604 } 605 606 $this->showItemSelection(); 607 } else { 608 if (count($this->getSources()) == 1) { 609 $this->copySingleObject(); 610 } else { 611 $this->copyMultipleNonContainer($this->getSources()); 612 } 613 } 614 } 615 616 /** 617 * set copy mode 618 * @param int $a_mode 619 * @return 620 */ 621 public function setMode($a_mode) 622 { 623 $this->mode = $a_mode; 624 } 625 626 /** 627 * get copy mode 628 * @return 629 */ 630 public function getMode() 631 { 632 return $this->mode; 633 } 634 635 public function setSubMode($a_mode) 636 { 637 $this->sub_mode = $a_mode; 638 } 639 640 public function getSubMode() 641 { 642 return $this->sub_mode; 643 } 644 645 /** 646 * Get parent gui object 647 * @return object parent gui 648 */ 649 public function getParentObject() 650 { 651 return $this->parent_obj; 652 } 653 654 /** 655 * Returns $type. 656 * 657 * @see ilObjectCopyGUI::$type 658 */ 659 public function getType() 660 { 661 return $this->type; 662 } 663 664 /** 665 * Sets $type. 666 * 667 * @param object $type 668 * @see ilObjectCopyGUI::$type 669 */ 670 public function setType($type) 671 { 672 $this->type = $type; 673 } 674 675 /** 676 * Set source id 677 * @param array $a_source_id 678 * @return 679 */ 680 public function setSource(array $a_source_ids) 681 { 682 $this->sources = $a_source_ids; 683 } 684 685 /** 686 * Get sources 687 * @return array 688 */ 689 public function getSources() 690 { 691 return (array) $this->sources; 692 } 693 694 public function getFirstSource() 695 { 696 if (count($this->sources)) { 697 return $this->sources[0]; 698 } 699 return 0; 700 } 701 702 // begin-patch mc 703 704 /** 705 * Set single object target 706 * @param type $a_ref_id 707 */ 708 public function setTarget($a_ref_id) 709 { 710 $this->setTargets(array($a_ref_id)); 711 } 712 713 714 /** 715 * Set target id 716 * @param int $a_target 717 * @return 718 */ 719 public function setTargets(array $a_target) 720 { 721 $this->targets = $a_target; 722 } 723 724 /** 725 * Get copy target 726 * @return 727 */ 728 public function getTargets() 729 { 730 return (array) $this->targets; 731 } 732 733 /** 734 * Get first target 735 * @return int 736 */ 737 public function getFirstTarget() 738 { 739 if (array_key_exists(0, $this->getTargets())) { 740 $targets = $this->getTargets(); 741 return $targets[0]; 742 } 743 return 0; 744 } 745 // end-patch multi copy 746 747 /** 748 * Cancel workflow 749 */ 750 protected function cancel() 751 { 752 $ilCtrl = $this->ctrl; 753 $ilCtrl->setReturnByClass(get_class($this->parent_obj), 'cancel'); 754 $ilCtrl->returnToParent($this); 755 } 756 757 /** 758 * Keep objects in clipboard 759 */ 760 public function keepObjectsInClipboard() 761 { 762 ilUtil::sendSuccess($this->lng->txt("obj_inserted_clipboard"), true); 763 $ilCtrl = $this->ctrl; 764 $_SESSION['clipboard']['cmd'] = "copy"; 765 $_SESSION['clipboard']['ref_ids'] = $this->getSources(); 766 $ilCtrl->returnToParent($this); 767 } 768 769 770 /** 771 * Search source 772 * @return 773 */ 774 protected function searchSource() 775 { 776 $tree = $this->tree; 777 $ilObjDataCache = $this->obj_data_cache; 778 $lng = $this->lng; 779 $ilCtrl = $this->ctrl; 780 $tpl = $this->tpl; 781 782 if (isset($_POST['tit'])) { 783 ilUtil::sendInfo($this->lng->txt('wizard_search_list')); 784 $_SESSION['source_query'] = $_POST['tit']; 785 } else { 786 $_POST['tit'] = $_SESSION['source_query']; 787 } 788 789 $this->initFormSearch(); 790 $this->form->setValuesByPost(); 791 792 if (!$this->form->checkInput()) { 793 ilUtil::sendFailure($lng->txt('msg_no_search_string'), true); 794 $ilCtrl->returnToParent($this); 795 return false; 796 } 797 798 include_once './Services/Search/classes/class.ilQueryParser.php'; 799 $query_parser = new ilQueryParser($this->form->getInput('tit')); 800 $query_parser->setMinWordLength(1, true); 801 $query_parser->setCombination(QP_COMBINATION_AND); 802 $query_parser->parse(); 803 if (!$query_parser->validate()) { 804 ilUtil::sendFailure($query_parser->getMessage(), true); 805 $ilCtrl->returnToParent($this); 806 } 807 808 // only like search since fulltext does not support search with less than 3 characters 809 include_once 'Services/Search/classes/Like/class.ilLikeObjectSearch.php'; 810 $object_search = new ilLikeObjectSearch($query_parser); 811 $object_search->setFilter(array($_REQUEST['new_type'])); 812 $res = $object_search->performSearch(); 813 $res->setRequiredPermission('copy'); 814 $res->filter(ROOT_FOLDER_ID, true); 815 816 if (!count($results = $res->getResultsByObjId())) { 817 ilUtil::sendFailure($this->lng->txt('search_no_match'), true); 818 $ilCtrl->returnToParent($this); 819 } 820 821 822 include_once './Services/Object/classes/class.ilObjectCopySearchResultTableGUI.php'; 823 $table = new ilObjectCopySearchResultTableGUI($this, 'searchSource', $this->getType()); 824 $table->setFormAction($ilCtrl->getFormAction($this)); 825 $table->setSelectedReference($this->getFirstSource()); 826 $table->parseSearchResults($results); 827 $tpl->setContent($table->getHTML()); 828 } 829 830 /** 831 * select source object 832 * @return 833 */ 834 protected function saveSource() 835 { 836 $objDefinition = $this->obj_definition; 837 $ilCtrl = $this->ctrl; 838 839 if (isset($_POST['source'])) { 840 $this->setSource(array((int) $_REQUEST['source'])); 841 $this->setType(ilObject::_lookupType((int) $_REQUEST['source'], true)); 842 $ilCtrl->setParameter($this, 'source_id', (int) $_REQUEST['source']); 843 } else { 844 ilUtil::sendFailure($this->lng->txt('select_one')); 845 $this->searchSource(); 846 return false; 847 } 848 849 // validate allowed subtypes 850 foreach ($this->getSources() as $source_ref_id) { 851 foreach ((array) $this->getTargets() as $target_ref_id) { 852 $target_type = ilObject::_lookupType($target_ref_id, true); 853 $target_class_name = ilObjectFactory::getClassByType($target_type); 854 $target_object = new $target_class_name($target_ref_id); 855 $possible_subtypes = $target_object->getPossibleSubObjects(); 856 857 $source_type = ilObject::_lookupType($source_ref_id, true); 858 859 if (!array_key_exists($source_type, $possible_subtypes)) { 860 #ilLoggerFactory::getLogger('obj')->debug('Source type: '. $source_type); 861 #ilLoggerFactory::getLogger('obj')->debug('Target type: '. $target_type); 862 #ilLoggerFactory::getLogger('obj')->debug('Submode: '. $this->getSubMode()); 863 864 // adopt content mode 865 if ( 866 $this->getSubMode() != self::SUBMODE_CONTENT_ONLY and 867 ($source_type != 'crs' or $target_type != 'crs') 868 ) { 869 ilUtil::sendFailure( 870 sprintf( 871 $this->lng->txt('msg_obj_may_not_contain_objects_of_type'), 872 $this->lng->txt('obj_' . $target_type), 873 $this->lng->txt('obj_' . $source_type) 874 ) 875 ); 876 $this->searchSource(); 877 return false; 878 } 879 } 880 } 881 } 882 883 884 if ($objDefinition->isContainer($this->getType())) { 885 $this->showItemSelection(); 886 } else { 887 $this->copySingleObject(); 888 } 889 } 890 891 /** 892 * Save selected source from membership screen 893 */ 894 protected function saveSourceMembership() 895 { 896 $objDefinition = $this->obj_definition; 897 $ilCtrl = $this->ctrl; 898 899 if (!isset($_REQUEST['source'])) { 900 ilUtil::sendFailure($this->lng->txt('select_one')); 901 $ilCtrl->redirect($this, 'showSourceSelectionMembership'); 902 return false; 903 } 904 905 $this->setSource(array((int) $_REQUEST['source'])); 906 $this->setType(ilObject::_lookupType((int) $this->getFirstSource(), true)); 907 $ilCtrl->setParameter($this, 'source_id', (int) $_REQUEST['source']); 908 909 if ($objDefinition->isContainer($this->getType())) { 910 $this->showItemSelection(); 911 } else { 912 $this->copySingleObject(); 913 } 914 } 915 916 /** 917 * 918 * @return 919 */ 920 protected function showItemSelection() 921 { 922 $tpl = $this->tpl; 923 924 if (!count($this->getSources())) { 925 ilUtil::sendFailure($this->lng->txt('select_one')); 926 $this->searchSource(); 927 return false; 928 } 929 930 ilLoggerFactory::getLogger('obj')->debug('Source(s): ' . print_r($this->getSources(), true)); 931 ilLoggerFactory::getLogger('obj')->debug('Target(s): ' . print_r($this->getTargets(), true)); 932 933 ilUtil::sendInfo($this->lng->txt($this->getType() . '_copy_threads_info')); 934 include_once './Services/Object/classes/class.ilObjectCopySelectionTableGUI.php'; 935 936 $tpl->addJavaScript('./Services/CopyWizard/js/ilContainer.js'); 937 $tpl->setVariable('BODY_ATTRIBUTES', 'onload="ilDisableChilds(\'cmd\');"'); 938 939 switch ($this->getMode()) { 940 case self::SOURCE_SELECTION: 941 $back_cmd = 'showSourceSelectionTree'; 942 break; 943 944 case self::TARGET_SELECTION: 945 $back_cmd = 'showTargetSelectionTree'; 946 break; 947 948 case self::SEARCH_SOURCE: 949 $back_cmd = 'searchSource'; 950 break; 951 } 952 953 $table = new ilObjectCopySelectionTableGUI($this, 'showItemSelection', $this->getType(), $back_cmd); 954 $table->parseSource($this->getFirstSource()); 955 956 $tpl->setContent($table->getHTML()); 957 } 958 959 /** 960 * Start cloning a single (not container) object 961 * @return 962 */ 963 protected function copySingleObject() 964 { 965 include_once('./Services/Link/classes/class.ilLink.php'); 966 include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php'); 967 968 $ilAccess = $this->access; 969 $ilErr = $this->error; 970 $rbacsystem = $this->rbacsystem; 971 $ilUser = $this->user; 972 $ilCtrl = $this->ctrl; 973 $rbacreview = $this->rbacreview; 974 975 // Source defined 976 if (!count($this->getSources())) { 977 ilUtil::sendFailure($this->lng->txt('select_one'), true); 978 $ilCtrl->returnToParent($this); 979 } 980 981 $this->copyMultipleNonContainer($this->getSources()); 982 return; 983 } 984 985 /** 986 * Copy multiple non container 987 * 988 * @param array $a_sources array of source ref ids 989 */ 990 public function copyMultipleNonContainer($a_sources) 991 { 992 $ilAccess = $this->access; 993 $objDefinition = $this->obj_definition; 994 $rbacsystem = $this->rbacsystem; 995 $ilUser = $this->user; 996 $ilCtrl = $this->ctrl; 997 $rbacreview = $this->rbacreview; 998 999 1000 include_once('./Services/Link/classes/class.ilLink.php'); 1001 include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php'); 1002 1003 // check permissions 1004 foreach ($a_sources as $source_ref_id) { 1005 $source_type = ilObject::_lookupType($source_ref_id, true); 1006 1007 // Create permission 1008 // begin-patch mc 1009 foreach ($this->getTargets() as $target_ref_id) { 1010 if (!$rbacsystem->checkAccess('create', $target_ref_id, $source_type)) { 1011 $this->log->notice('Permission denied for target_id: ' . $target_ref_id . ' source_type: ' . $source_type . ' CREATE'); 1012 ilUtil::sendFailure($this->lng->txt('permission_denied'), true); 1013 $ilCtrl->returnToParent($this); 1014 } 1015 } 1016 1017 // Copy permission 1018 if (!$ilAccess->checkAccess('copy', '', $source_ref_id)) { 1019 $this->log->notice('Permission denied for source_ref_id: ' . $source_ref_id . ' COPY'); 1020 ilUtil::sendFailure($this->lng->txt('permission_denied'), true); 1021 $ilCtrl->returnToParent($this); 1022 } 1023 1024 // check that these objects are really not containers 1025 if ($objDefinition->isContainer($source_type) and $this->getSubMode() != self::SUBMODE_CONTENT_ONLY) { 1026 ilUtil::sendFailure($this->lng->txt('cntr_container_only_on_their_own'), true); 1027 $ilCtrl->returnToParent($this); 1028 } 1029 } 1030 1031 reset($a_sources); 1032 1033 1034 ilLoggerFactory::getLogger('obj')->debug('Copy multiple non containers. Sources: ' . print_r($a_sources, true)); 1035 1036 // clone 1037 foreach ($a_sources as $source_ref_id) { 1038 ilLoggerFactory::getLogger('obj')->debug('Copying source ref_id : ' . $source_ref_id); 1039 1040 // begin-patch mc 1041 foreach ($this->getTargets() as $target_ref_id) { 1042 // Save wizard options 1043 $copy_id = ilCopyWizardOptions::_allocateCopyId(); 1044 $wizard_options = ilCopyWizardOptions::_getInstance($copy_id); 1045 $wizard_options->saveOwner($ilUser->getId()); 1046 $wizard_options->saveRoot((int) $source_ref_id); 1047 $wizard_options->read(); 1048 1049 $orig = ilObjectFactory::getInstanceByRefId((int) $source_ref_id); 1050 $new_obj = $orig->cloneObject($target_ref_id, $copy_id); 1051 1052 // Delete wizard options 1053 $wizard_options->deleteAll(); 1054 1055 // rbac log 1056 include_once "Services/AccessControl/classes/class.ilRbacLog.php"; 1057 if (ilRbacLog::isActive()) { 1058 $rbac_log_roles = $rbacreview->getParentRoleIds($new_obj->getRefId(), false); 1059 $rbac_log = ilRbacLog::gatherFaPa($new_obj->getRefId(), array_keys($rbac_log_roles), true); 1060 ilRbacLog::add(ilRbacLog::COPY_OBJECT, $new_obj->getRefId(), $rbac_log, (int) $source_ref_id); 1061 } 1062 } 1063 } 1064 1065 unset($_SESSION["clipboard"]["ref_ids"]); 1066 unset($_SESSION["clipboard"]["cmd"]); 1067 1068 if (count($a_sources) == 1) { 1069 ilLoggerFactory::getLogger('obj')->info('Object copy completed.'); 1070 ilUtil::sendSuccess($this->lng->txt("object_duplicated"), true); 1071 $ref_id = $new_obj->getRefId(); 1072 } else { 1073 ilLoggerFactory::getLogger('obj')->info('Object copy completed.'); 1074 ilUtil::sendSuccess($this->lng->txt("objects_duplicated"), true); 1075 $ref_id = $this->getFirstTarget(); 1076 } 1077 1078 ilUtil::sendSuccess($this->lng->txt("objects_duplicated"), true); 1079 ilUtil::redirect(ilLink::_getLink($ref_id)); 1080 1081 // see bug discussion 24472 1082 /* 1083 $gui_fac = new ilObjectGUIFactory(); 1084 $obj_gui = $gui_fac->getInstanceByRefId($ref_id); 1085 $obj_gui->redirectAfterCreation(); 1086 */ 1087 } 1088 1089 /** 1090 * Copy to multiple targets 1091 */ 1092 protected function copyContainerToTargets() 1093 { 1094 $ilCtrl = $this->ctrl; 1095 1096 ilLoggerFactory::getLogger('obj')->debug('Copy container to targets: ' . print_r($_REQUEST, true)); 1097 ilLoggerFactory::getLogger('obj')->debug('Source(s): ' . print_r($this->getSources(), true)); 1098 ilLoggerFactory::getLogger('obj')->debug('Target(s): ' . print_r($this->getTargets(), true)); 1099 1100 1101 $last_target = 0; 1102 $result = 1; 1103 foreach ($this->getTargets() as $target_ref_id) { 1104 $result = $this->copyContainer($target_ref_id); 1105 $last_target = $target_ref_id; 1106 } 1107 1108 unset($_SESSION["clipboard"]["ref_ids"]); 1109 unset($_SESSION["clipboard"]["cmd"]); 1110 1111 include_once './Services/CopyWizard/classes/class.ilCopyWizardOptions.php'; 1112 if (ilCopyWizardOptions::_isFinished($result['copy_id'])) { 1113 ilLoggerFactory::getLogger('obj')->info('Object copy completed.'); 1114 ilUtil::sendSuccess($this->lng->txt("object_duplicated"), true); 1115 if ($this->getSubMode() == self::SUBMODE_CONTENT_ONLY) { 1116 // return to parent container 1117 return $this->ctrl->returnToParent($this); 1118 } 1119 // return to last target 1120 $link = ilLink::_getLink($result['ref_id']); 1121 $ilCtrl->redirectToUrl($link); 1122 } else { 1123 // show progress 1124 ilLoggerFactory::getLogger('obj')->debug('Object copy in progress.'); 1125 return $this->showCopyProgress(); 1126 } 1127 } 1128 1129 /** 1130 * Show progress for copying 1131 */ 1132 protected function showCopyProgress() 1133 { 1134 $ilCtrl = $this->ctrl; 1135 $tpl = $this->tpl; 1136 1137 include_once './Services/Object/classes/class.ilObjectCopyProgressTableGUI.php'; 1138 $progress = new ilObjectCopyProgressTableGUI( 1139 $this, 1140 'showCopyProgress', 1141 (int) $_GET['ref_id'] 1142 ); 1143 $progress->setObjectInfo($this->targets_copy_id); 1144 $progress->parse(); 1145 $progress->init(); 1146 $progress->setRedirectionUrl($ilCtrl->getParentReturn($this->parent_obj)); 1147 1148 $tpl->setContent($progress->getHTML()); 1149 } 1150 1151 /** 1152 * Update progress 1153 */ 1154 protected function updateProgress() 1155 { 1156 $json = new stdClass(); 1157 $json->percentage = null; 1158 $json->performed_steps = null; 1159 1160 include_once './Services/CopyWizard/classes/class.ilCopyWizardOptions.php'; 1161 $options = ilCopyWizardOptions::_getInstance((int) $_REQUEST['copy_id']); 1162 $json->required_steps = $options->getRequiredSteps(); 1163 $json->id = (int) $_REQUEST['copy_id']; 1164 1165 ilLoggerFactory::getLogger('obj')->debug('Update copy progress: ' . json_encode($json)); 1166 1167 echo json_encode($json); 1168 exit; 1169 } 1170 1171 1172 /** 1173 * Copy a container 1174 * @return 1175 */ 1176 protected function copyContainer($a_target) 1177 { 1178 $ilLog = $this->log; 1179 $ilCtrl = $this->ctrl; 1180 1181 include_once('./Services/Link/classes/class.ilLink.php'); 1182 include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php'); 1183 1184 $ilAccess = $this->access; 1185 $ilErr = $this->error; 1186 $rbacsystem = $this->rbacsystem; 1187 $tree = $this->tree; 1188 $ilUser = $this->user; 1189 $ilCtrl = $this->ctrl; 1190 1191 // Workaround for course in course copy 1192 1193 $target_type = ilObject::_lookupType(ilObject::_lookupObjId($a_target)); 1194 $source_type = ilObject::_lookupType(ilObject::_lookupObjId($this->getFirstSource())); 1195 1196 if ($this->getSubMode() != self::SUBMODE_CONTENT_ONLY) { 1197 if (!$rbacsystem->checkAccess('create', $a_target, $this->getType())) { 1198 $this->log->notice('Permission denied for target: ' . $a_target . ' type: ' . $this->getType() . ' CREATE'); 1199 ilUtil::sendFailure($this->lng->txt('permission_denied'), true); 1200 $ilCtrl->returnToParent($this); 1201 } 1202 } 1203 if (!$this->getFirstSource()) { 1204 ilUtil::sendFailure($this->lng->txt('select_one'), true); 1205 $ilCtrl->returnToParent($this); 1206 return false; 1207 } 1208 1209 $options = $_POST['cp_options'] ? $_POST['cp_options'] : array(); 1210 1211 1212 ilLoggerFactory::getLogger('obj')->debug('Copy container (sources): ' . print_r($this->getSources(), true)); 1213 1214 $orig = ilObjectFactory::getInstanceByRefId($this->getFirstSource()); 1215 $result = $orig->cloneAllObject( 1216 $_COOKIE[session_name()], 1217 $_COOKIE['ilClientId'], 1218 $this->getType(), 1219 $a_target, 1220 $this->getFirstSource(), 1221 $options, 1222 false, 1223 $this->getSubMode() 1224 ); 1225 1226 $this->targets_copy_id[$a_target] = $result['copy_id']; 1227 1228 return $result; 1229 } 1230 1231 1232 1233 /** 1234 * Show init screen 1235 * Normally shown below the create and import form when creating a new object 1236 * 1237 * @param string $a_tplvar The tpl variable to fill 1238 * @return 1239 */ 1240 public function showSourceSearch($a_tplvar) 1241 { 1242 $tpl = $this->tpl; 1243 1244 // Disabled for performance 1245 #if(!$this->sourceExists()) 1246 #{ 1247 # return false; 1248 #} 1249 1250 $this->unsetSession(); 1251 $this->initFormSearch(); 1252 1253 if ($a_tplvar) { 1254 $tpl->setVariable($a_tplvar, $this->form->getHTML()); 1255 } else { 1256 return $this->form; 1257 } 1258 } 1259 1260 1261 /** 1262 * Check if there is any source object 1263 * @return bool 1264 */ 1265 protected function sourceExists() 1266 { 1267 $ilUser = $this->user; 1268 1269 return (bool) ilUtil::_getObjectsByOperations($this->getType(), 'copy', $ilUser->getId(), 1); 1270 } 1271 1272 /** 1273 * Init search form 1274 * @return 1275 */ 1276 protected function initFormSearch() 1277 { 1278 $lng = $this->lng; 1279 $ilCtrl = $this->ctrl; 1280 1281 include_once './Services/Form/classes/class.ilPropertyFormGUI.php'; 1282 $this->form = new ilPropertyFormGUI(); 1283 $this->form->setTableWidth('600px'); 1284 1285 $ilCtrl->setParameter($this, 'new_type', $this->getType()); 1286 1287 #$ilCtrl->setParameter($this, 'cp_mode', self::SOURCE_SELECTION); 1288 $this->form->setFormAction($ilCtrl->getFormAction($this)); 1289 $this->form->setTitle($lng->txt($this->getType() . '_copy')); 1290 1291 $this->form->addCommandButton('searchSource', $lng->txt('btn_next')); 1292 $this->form->addCommandButton('cancel', $this->lng->txt('cancel')); 1293 1294 $tit = new ilTextInputGUI($lng->txt('title'), 'tit'); 1295 $tit->setSize(40); 1296 $tit->setMaxLength(70); 1297 $tit->setRequired(true); 1298 $tit->setInfo($lng->txt('wizard_title_info')); 1299 $this->form->addItem($tit); 1300 } 1301 1302 /** 1303 * Unset session variables 1304 * @return 1305 */ 1306 protected function unsetSession() 1307 { 1308 unset($_SESSION['source_query']); 1309 $this->setSource(array()); 1310 } 1311} 1312