1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
5/**
6* Class ilObjectGUI
7* Basic methods of all Output classes
8*
9* @author Stefan Meyer <meyer@leifos.com>
10* @version $Id$
11*
12*/
13class ilObjectGUI
14{
15    /**
16     * @var ilErrorHandling
17     */
18    protected $ilErr;
19
20    /**
21     * @var ilLocatorGUI
22     */
23    protected $locator;
24
25    /**
26     * @var ilObjUser
27     */
28    protected $user;
29
30    /**
31     * @var ilAccessHandler
32     */
33    protected $access;
34
35    /**
36     * @var ilSetting
37     */
38    protected $settings;
39
40    /**
41     * @var ilRbacReview
42     */
43    protected $rbacreview;
44
45    /**
46     * @var ilToolbarGUI
47     */
48    protected $toolbar;
49
50    const COPY_WIZARD_NEEDS_PAGE = 1;
51
52
53    /**
54    * object Definition Object
55    * @var		object ilias
56    * @access	private
57    */
58    public $objDefinition;
59
60    /**
61    * template object
62    * @var		object ilias
63    * @access	private
64    */
65    public $tpl;
66
67    /**
68    * tree object
69    * @var		object ilias
70    * @access	private
71    */
72    public $tree;
73
74    /**
75    * language object
76    * @var		object language (of ilObject)
77    * @access	private
78    */
79    public $lng;
80
81    /**
82    * output data
83    * @var		data array
84    * @access	private
85    */
86    public $data;
87
88    /**
89    * object
90    * @var          object
91    * @access       private
92    */
93    public $object;
94    public $ref_id;
95    public $obj_id;
96    public $maxcount;			// contains number of child objects
97    public $formaction;		// special formation (array "cmd" => "formaction")
98    public $return_location;	// special return location (array "cmd" => "location")
99    public $target_frame;	// special target frame (array "cmd" => "location")
100    protected $tmp_import_dir;	// directory used during import
101
102    public $tab_target_script;
103    public $actions;
104    public $sub_objects;
105    public $omit_locator = false;
106
107    /**
108     * @var ilTabsGUI
109     */
110    protected $tabs_gui = null;
111
112    /**
113     * @var ilCtrl
114     */
115    protected $ctrl;
116
117    /**
118     * @var ilObjectService
119     */
120    protected $object_service;
121
122    const CFORM_NEW = 1;
123    const CFORM_IMPORT = 2;
124    const CFORM_CLONE = 3;
125
126    /**
127    * Constructor
128    * @access	public
129    * @param	array	??
130    * @param	integer	object id
131    * @param	boolean	call be reference
132    */
133    public function __construct($a_data, $a_id = 0, $a_call_by_reference = true, $a_prepare_output = true)
134    {
135        global $DIC;
136
137        $this->locator = $DIC["ilLocator"];
138        $this->user = $DIC->user();
139        $this->access = $DIC->access();
140        $this->settings = $DIC->settings();
141        $this->rbacreview = $DIC->rbac()->review();
142        $this->toolbar = $DIC->toolbar();
143        $this->object_service = $DIC->object();
144        $objDefinition = $DIC["objDefinition"];
145        $tpl = $DIC["tpl"];
146        $tree = $DIC->repositoryTree();
147        $ilCtrl = $DIC->ctrl();
148        $ilErr = $DIC["ilErr"];
149        $lng = $DIC->language();
150        $ilTabs = $DIC->tabs();
151
152        $this->ilias = $DIC["ilias"];
153
154        /**
155         * @var ilTab
156         */
157        $this->tabs_gui = $ilTabs;
158
159        if (!isset($ilErr)) {
160            $ilErr = new ilErrorHandling();
161            $ilErr->setErrorHandling(PEAR_ERROR_CALLBACK, array($ilErr,'errorHandler'));
162        } else {
163            $this->ilErr = $ilErr;
164        }
165
166        $this->objDefinition = $objDefinition;
167        $this->tpl = $tpl;
168        $this->html = "";
169        $this->ctrl = $ilCtrl;
170
171        $params = array("ref_id");
172
173        if (!$a_call_by_reference) {
174            $params = array("ref_id","obj_id");
175        }
176
177        $this->ctrl->saveParameter($this, $params);
178
179        $this->lng = $lng;
180        $this->tree = $tree;
181        $this->formaction = array();
182        $this->return_location = array();
183        $this->target_frame = array();
184        $this->actions = "";
185        $this->sub_objects = "";
186
187        $this->data = $a_data;
188        $this->id = $a_id;
189        $this->call_by_reference = $a_call_by_reference;
190        $this->prepare_output = $a_prepare_output;
191        $this->creation_mode = false;
192
193        $this->ref_id = ($this->call_by_reference) ? $this->id : $_GET["ref_id"];
194        $this->obj_id = ($this->call_by_reference) ? $_GET["obj_id"] : $this->id;
195
196        if ($this->id != 0) {
197            $this->link_params = "ref_id=" . $this->ref_id;
198        }
199
200        // get the object
201        $this->assignObject();
202
203        // set context
204        if (is_object($this->object)) {
205            if ($this->call_by_reference && $this->ref_id == $_GET["ref_id"]) {
206                $this->ctrl->setContext(
207                    $this->object->getId(),
208                    $this->object->getType()
209                );
210            }
211        }
212
213        //prepare output
214        if ($a_prepare_output) {
215            $this->prepareOutput();
216        }
217    }
218
219    /**
220     * Get object service
221     *
222     * @return ilObjectService
223     */
224    protected function getObjectService()
225    {
226        return $this->object_service;
227    }
228
229    /**
230    * execute command
231    */
232    public function executeCommand()
233    {
234        $next_class = $this->ctrl->getNextClass($this);
235        $cmd = $this->ctrl->getCmd();
236
237        switch ($next_class) {
238            default:
239                $this->prepareOutput();
240                if (!$cmd) {
241                    $cmd = "view";
242                }
243                $cmd .= "Object";
244                $this->$cmd();
245
246                break;
247        }
248
249        return true;
250    }
251
252
253    /**
254    * determines wether objects are referenced or not (got ref ids or not)
255    */
256    public function withReferences()
257    {
258        return $this->call_by_reference;
259    }
260
261    /**
262    * if true, a creation screen is displayed
263    * the current $_GET[ref_id] don't belong
264    * to the current class!
265    * the mode is determined in ilrepositorygui
266    */
267    public function setCreationMode($a_mode = true)
268    {
269        $this->creation_mode = $a_mode;
270    }
271
272    /**
273    * get creation mode
274    */
275    public function getCreationMode()
276    {
277        return $this->creation_mode;
278    }
279
280    protected function assignObject()
281    {
282        // TODO: it seems that we always have to pass only the ref_id
283        //echo "<br>ilObjectGUIassign:".get_class($this).":".$this->id.":<br>";
284        if ($this->id != 0) {
285            if ($this->call_by_reference) {
286                $this->object = ilObjectFactory::getInstanceByRefId($this->id);
287            } else {
288                $this->object = ilObjectFactory::getInstanceByObjId($this->id);
289            }
290        }
291    }
292
293    /**
294    * prepare output
295    */
296    public function prepareOutput($a_show_subobjects = true)
297    {
298        $ilLocator = $this->locator;
299        $tpl = $this->tpl;
300        $ilUser = $this->user;
301
302        $this->tpl->getStandardTemplate();
303        // administration prepare output
304        if (strtolower($_GET["baseClass"]) == "iladministrationgui") {
305            $this->addAdminLocatorItems();
306            $tpl->setLocator();
307
308            //			ilUtil::sendInfo();
309            ilUtil::infoPanel();
310
311            $this->setTitleAndDescription();
312
313            if ($this->getCreationMode() != true) {
314                $this->setAdminTabs();
315            }
316
317            return false;
318        }
319        // set locator
320        $this->setLocator();
321        // catch feedback message
322        //		ilUtil::sendInfo();
323        ilUtil::infoPanel();
324
325        // in creation mode (parent) object and gui object
326        // do not fit
327        if ($this->getCreationMode() == true) {
328            // repository vs. workspace
329            if ($this->call_by_reference) {
330                // get gui class of parent and call their title and description method
331                $obj_type = ilObject::_lookupType($_GET["ref_id"], true);
332                $class_name = $this->objDefinition->getClassName($obj_type);
333                $class = strtolower("ilObj" . $class_name . "GUI");
334                $class_path = $this->ctrl->lookupClassPath($class);
335                include_once($class_path);
336                $class_name = $this->ctrl->getClassForClasspath($class_path);
337                //echo "<br>instantiating parent for title and description";
338                $this->parent_gui_obj = new $class_name("", $_GET["ref_id"], true, false);
339                // the next line prevents the header action menu being shown
340                $this->parent_gui_obj->setCreationMode(true);
341                $this->parent_gui_obj->setTitleAndDescription();
342            }
343        } else {
344            // set title and description and title icon
345            $this->setTitleAndDescription();
346
347            // set tabs
348            $this->setTabs();
349
350            // BEGIN WebDAV: Display Mount Webfolder icon.
351            if ($ilUser->getId() != ANONYMOUS_USER_ID) {
352                require_once('Services/WebDAV/classes/class.ilDAVActivationChecker.php');
353                if (ilDAVActivationChecker::_isActive()) {
354                    $this->showMountWebfolderIcon();
355                }
356            }
357            // END WebDAV: Display Mount Webfolder icon.
358
359            // fileupload support
360            require_once './Services/FileUpload/classes/class.ilFileUploadUtil.php';
361            if (ilFileUploadUtil::isUploadAllowed($this->ref_id, $this->object->getType())) {
362                $this->enableDragDropFileUpload();
363            }
364        }
365
366        return true;
367    }
368
369    /**
370    * called by prepare output
371    */
372    protected function setTitleAndDescription()
373    {
374        if (!is_object($this->object)) {
375            if ((int) $_REQUEST["crtptrefid"] > 0) {
376                $cr_obj_id = ilObject::_lookupObjId((int) $_REQUEST["crtcb"]);
377                $this->tpl->setTitle(ilObject::_lookupTitle($cr_obj_id));
378                $this->tpl->setTitleIcon(ilObject::_getIcon($cr_obj_id));
379            }
380            return;
381        }
382        $this->tpl->setTitle($this->object->getPresentationTitle());
383        $this->tpl->setDescription($this->object->getLongDescription());
384
385        if (strtolower($_GET["baseClass"]) == "iladministrationgui") {
386            // alt text would be same as heading -> empty alt text
387            $this->tpl->setTitleIcon(ilObject::_getIcon("", "big", $this->object->getType()));
388        } else {
389            $this->tpl->setTitleIcon(
390                ilObject::_getIcon("", "big", $this->object->getType()),
391                $this->lng->txt("obj_" . $this->object->getType())
392            );
393        }
394
395        include_once './Services/Object/classes/class.ilObjectListGUIFactory.php';
396        $lgui = ilObjectListGUIFactory::_getListGUIByType($this->object->getType());
397        $lgui->initItem($this->object->getRefId(), $this->object->getId());
398        $this->tpl->setAlertProperties($lgui->getAlertProperties());
399    }
400
401    /**
402     * Add header action menu
403     *
404     * @param string $a_sub_type
405     * @param int $a_sub_id
406     * @return ilObjectListGUI
407     */
408    protected function initHeaderAction($a_sub_type = null, $a_sub_id = null)
409    {
410        $ilAccess = $this->access;
411
412        if (!$this->creation_mode && $this->object) {
413            include_once "Services/Object/classes/class.ilCommonActionDispatcherGUI.php";
414            $dispatcher = new ilCommonActionDispatcherGUI(
415                ilCommonActionDispatcherGUI::TYPE_REPOSITORY,
416                $ilAccess,
417                $this->object->getType(),
418                $this->ref_id,
419                $this->object->getId()
420            );
421
422            $dispatcher->setSubObject($a_sub_type, $a_sub_id);
423
424            include_once "Services/Object/classes/class.ilObjectListGUI.php";
425            ilObjectListGUI::prepareJSLinks(
426                $this->ctrl->getLinkTarget($this, "redrawHeaderAction", "", true),
427                $this->ctrl->getLinkTargetByClass(array("ilcommonactiondispatchergui", "ilnotegui"), "", "", true, false),
428                $this->ctrl->getLinkTargetByClass(array("ilcommonactiondispatchergui", "iltagginggui"), "", "", true, false)
429            );
430
431            $lg = $dispatcher->initHeaderAction();
432
433            if (is_object($lg)) {
434                // to enable add to desktop / remove from desktop
435                if ($this instanceof ilDesktopItemHandling) {
436                    $lg->setContainerObject($this);
437                }
438
439                // enable multi download
440                $lg->enableMultiDownload(true);
441
442                // comments settings are always on (for the repository)
443                // should only be shown if active or permission to toggle
444                include_once "Services/Notes/classes/class.ilNote.php";
445                if ($ilAccess->checkAccess("write", "", $this->ref_id) ||
446                    $ilAccess->checkAccess("edit_permissions", "", $this->ref_id) ||
447                    ilNote::commentsActivated($this->object->getId(), 0, $this->object->getType())) {
448                    $lg->enableComments(true);
449                }
450
451                $lg->enableNotes(true);
452                $lg->enableTags(true);
453            }
454
455            return $lg;
456        }
457    }
458
459    /**
460     * Insert header action into main template
461     *
462     * @param ilObjectListGUI $a_list_gui
463     */
464    protected function insertHeaderAction($a_list_gui)
465    {
466        if (!is_object($this->object) || ilContainer::_lookupContainerSetting($this->object->getId(), "hide_top_actions")) {
467            return;
468        }
469
470        if (is_object($a_list_gui)) {
471            $this->tpl->setHeaderActionMenu($a_list_gui->getHeaderAction());
472        }
473    }
474
475    /**
476     * Add header action menu
477     */
478    protected function addHeaderAction()
479    {
480        $this->insertHeaderAction($this->initHeaderAction());
481    }
482
483    /**
484     * Ajax call: redraw action header only
485     */
486    protected function redrawHeaderActionObject()
487    {
488        $tpl = $this->tpl;
489
490        $lg = $this->initHeaderAction();
491        echo $lg->getHeaderAction();
492
493        // we need to add onload code manually (rating, comments, etc.)
494        echo $tpl->getOnLoadCodeForAsynch();
495
496        exit;
497    }
498
499    // BEGIN WebDAV: Show Mount Webfolder Icon.
500    protected function showMountWebfolderIcon()
501    {
502        $tree = $this->tree;
503        $tpl = $this->tpl;
504        $objDefinition = $this->objDefinition;
505
506        if ($this->object->getRefId() == "") {
507            return;
508        }
509
510        $tpl->setMountWebfolderIcon($this->object->getRefId());
511    }
512    // END WebDAV: Show Mount Webfolder Icon.
513
514
515    /**
516    * set admin tabs
517    * @access	public
518    */
519    protected function setTabs()
520    {
521        $this->getTabs();
522    }
523
524    /**
525    * set admin tabs
526    * @access	public
527    */
528    final protected function setAdminTabs()
529    {
530        $this->getAdminTabs();
531    }
532
533    /**
534    * administration tabs show only permissions and trash folder
535    */
536    public function getAdminTabs()
537    {
538        $tree = $this->tree;
539
540        /*		if ($_GET["admin_mode"] == "repository")
541                {
542                    $this->ctrl->setParameterByClass("iladministrationgui", "admin_mode", "settings");
543                    $this->tabs_gui->setBackTarget($this->lng->txt("administration"),
544                        $this->ctrl->getLinkTargetByClass("iladministrationgui", "frameset"),
545                        ilFrameTargetInfo::_getFrame("MainContent"));
546                    $this->ctrl->setParameterByClass("iladministrationgui", "admin_mode", "repository");
547                }*/
548
549        if ($this->checkPermissionBool("visible,read")) {
550            $this->tabs_gui->addTarget(
551                "view",
552                $this->ctrl->getLinkTarget($this, "view"),
553                array("", "view"),
554                get_class($this)
555            );
556        }
557
558        if ($this->checkPermissionBool("edit_permission")) {
559            $this->tabs_gui->addTarget(
560                "perm_settings",
561                $this->ctrl->getLinkTargetByClass(array(get_class($this),'ilpermissiongui'), "perm"),
562                "",
563                "ilpermissiongui"
564            );
565        }
566
567        if ($tree->getSavedNodeData($this->object->getRefId())) {
568            $this->tabs_gui->addTarget(
569                "trash",
570                $this->ctrl->getLinkTarget($this, "trash"),
571                "trash",
572                get_class($this)
573            );
574        }
575    }
576
577
578    public function getHTML()
579    {
580        return $this->html;
581    }
582
583
584    /**
585    * set possible actions for objects in list. if actions are set
586    * via this method, the values of objects.xml are ignored.
587    *
588    * @param	array		$a_actions		array with $command => $lang_var pairs
589    */
590    final private function setActions($a_actions = "")
591    {
592        if (is_array($a_actions)) {
593            foreach ($a_actions as $name => $lng) {
594                $this->actions[$name] = array("name" => $name, "lng" => $lng);
595            }
596        } else {
597            $this->actions = "";
598        }
599    }
600
601    /**
602    * set possible subobjects for this object. if subobjects are set
603    * via this method, the values of objects.xml are ignored.
604    *
605    * @param	array		$a_actions		array with $command => $lang_var pairs
606    */
607    final private function setSubObjects($a_sub_objects = "")
608    {
609        if (is_array($a_sub_objects)) {
610            foreach ($a_sub_objects as $name => $options) {
611                $this->sub_objects[$name] = array("name" => $name, "max" => $options["max"]);
612            }
613        } else {
614            $this->sub_objects = "";
615        }
616    }
617
618    /**
619    * set Locator
620    *
621    * @param	object	tree object
622    * @param	integer	reference id
623    * @param	scriptanme that is used for linking;
624    * @access	public
625    */
626    protected function setLocator()
627    {
628        $ilLocator = $this->locator;
629        $tpl = $this->tpl;
630
631        if ($this->omit_locator) {
632            return;
633        }
634
635        // repository vs. workspace
636        if ($this->call_by_reference) {
637            // todo: admin workaround
638            // in the future, objectgui classes should not be called in
639            // admin section anymore (rbac/trash handling in own classes)
640            $ref_id = ($_GET["ref_id"] != "")
641                ? $_GET["ref_id"]
642                : $this->object->getRefId();
643            $ilLocator->addRepositoryItems($ref_id);
644        }
645
646        if (!$this->creation_mode) {
647            $this->addLocatorItems();
648        }
649
650        $tpl->setLocator();
651    }
652
653    /**
654    * should be overwritten to add object specific items
655    * (repository items are preloaded)
656    */
657    protected function addLocatorItems()
658    {
659    }
660
661    protected function omitLocator($a_omit = true)
662    {
663        $this->omit_locator = $a_omit;
664    }
665
666    /**
667    * should be overwritten to add object specific items
668    * (repository items are preloaded)
669    *
670    * @param bool $a_do_not_add_object
671    */
672    protected function addAdminLocatorItems($a_do_not_add_object = false)
673    {
674        $ilLocator = $this->locator;
675
676        if ($_GET["admin_mode"] == "settings") {	// system settings
677            $this->ctrl->setParameterByClass(
678                "ilobjsystemfoldergui",
679                "ref_id",
680                SYSTEM_FOLDER_ID
681            );
682            $ilLocator->addItem(
683                $this->lng->txt("administration"),
684                $this->ctrl->getLinkTargetByClass(array("iladministrationgui", "ilobjsystemfoldergui"), "")
685            );
686            if ($this->object && ($this->object->getRefId() != SYSTEM_FOLDER_ID && !$a_do_not_add_object)) {
687                $ilLocator->addItem(
688                    $this->object->getTitle(),
689                    $this->ctrl->getLinkTarget($this, "view")
690                );
691            }
692        } else {							// repository administration
693            $this->ctrl->setParameterByClass(
694                "iladministrationgui",
695                "ref_id",
696                ""
697            );
698            $this->ctrl->setParameterByClass(
699                "iladministrationgui",
700                "admin_mode",
701                "settings"
702            );
703            //$ilLocator->addItem($this->lng->txt("administration"),
704            //	$this->ctrl->getLinkTargetByClass("iladministrationgui", "frameset"),
705            //	ilFrameTargetInfo::_getFrame("MainContent"));
706            $this->ctrl->clearParametersByClass("iladministrationgui");
707            $ilLocator->addAdministrationItems();
708        }
709    }
710
711    /**
712    * confirmed deletion of object -> objects are moved to trash or deleted
713    * immediately, if trash is disabled
714    */
715    public function confirmedDeleteObject()
716    {
717        if (isset($_POST["mref_id"])) {
718            $_SESSION["saved_post"] = array_unique(array_merge($_SESSION["saved_post"], $_POST["mref_id"]));
719        }
720
721        include_once("./Services/Repository/classes/class.ilRepUtilGUI.php");
722        $ru = new ilRepUtilGUI($this);
723        $ru->deleteObjects($_GET["ref_id"], ilSession::get("saved_post"));
724        ilSession::clear("saved_post");
725        $this->ctrl->returnToParent($this);
726    }
727
728    /**
729    * cancel deletion of object
730    *
731    * @access	public
732    */
733    public function cancelDeleteObject()
734    {
735        ilSession::clear("saved_post");
736        $this->ctrl->returnToParent($this);
737    }
738
739
740    /**
741    * cancel action and go back to previous page
742    * @access	public
743    *
744    */
745    public function cancelObject()
746    {
747        ilSession::clear("saved_post");
748        $this->ctrl->returnToParent($this);
749    }
750
751    /**
752    * create new object form
753    *
754    * @access	public
755    */
756    public function createObject()
757    {
758        $tpl = $this->tpl;
759        $ilErr = $this->ilErr;
760
761        $new_type = $_REQUEST["new_type"];
762
763
764        // add new object to custom parent container
765        $this->ctrl->saveParameter($this, "crtptrefid");
766        // use forced callback after object creation
767        $this->ctrl->saveParameter($this, "crtcb");
768
769        if (!$this->checkPermissionBool("create", "", $new_type)) {
770            $ilErr->raiseError($this->lng->txt("permission_denied"), $ilErr->MESSAGE);
771        } else {
772            $this->lng->loadLanguageModule($new_type);
773            $this->ctrl->setParameter($this, "new_type", $new_type);
774
775            $forms = $this->initCreationForms($new_type);
776
777            // copy form validation error: do not show other creation forms
778            if ($_GET["cpfl"] && isset($forms[self::CFORM_CLONE])) {
779                $forms = array(self::CFORM_CLONE => $forms[self::CFORM_CLONE]);
780            }
781            $tpl->setContent($this->getCreationFormsHTML($forms));
782        }
783    }
784
785    /**
786     * Init creation froms
787     *
788     * this will create the default creation forms: new, import, clone
789     *
790     * @param	string	$a_new_type
791     * @return	array
792     */
793    protected function initCreationForms($a_new_type)
794    {
795        $forms = array(
796            self::CFORM_NEW => $this->initCreateForm($a_new_type),
797            self::CFORM_IMPORT => $this->initImportForm($a_new_type),
798            self::CFORM_CLONE => $this->fillCloneTemplate(null, $a_new_type)
799            );
800
801        return $forms;
802    }
803
804    /**
805     * Get HTML for creation forms (accordion)
806     *
807     * @param array $a_forms
808     */
809    final protected function getCreationFormsHTML(array $a_forms)
810    {
811        $tpl = $this->tpl;
812
813        // #13168- sanity check
814        foreach ($a_forms as $id => $form) {
815            if (!$form instanceof ilPropertyFormGUI) {
816                unset($a_forms[$id]);
817            }
818        }
819
820        // no accordion if there is just one form
821        if (sizeof($a_forms) == 1) {
822            $form_type = key($a_forms);
823            $a_forms = array_shift($a_forms);
824
825            // see bug #0016217
826            if (method_exists($this, "getCreationFormTitle")) {
827                $form_title = $this->getCreationFormTitle($form_type);
828                if ($form_title != "") {
829                    $a_forms->setTitle($form_title);
830                }
831            }
832            return $a_forms->getHTML();
833        } else {
834            include_once("./Services/Accordion/classes/class.ilAccordionGUI.php");
835
836            $acc = new ilAccordionGUI();
837            $acc->setBehaviour(ilAccordionGUI::FIRST_OPEN);
838            $cnt = 1;
839            foreach ($a_forms as $form_type => $cf) {
840                $htpl = new ilTemplate("tpl.creation_acc_head.html", true, true, "Services/Object");
841
842                // using custom form titles (used for repository plugins)
843                $form_title = "";
844                if (method_exists($this, "getCreationFormTitle")) {
845                    $form_title = $this->getCreationFormTitle($form_type);
846                }
847                if (!$form_title) {
848                    $form_title = $cf->getTitle();
849                }
850
851                // move title from form to accordion
852                $htpl->setVariable("TITLE", $this->lng->txt("option") . " " . $cnt . ": " .
853                    $form_title);
854                $cf->setTitle(null);
855                $cf->setTitleIcon(null);
856                $cf->setTableWidth("100%");
857
858                $acc->addItem($htpl->get(), $cf->getHTML());
859
860                $cnt++;
861            }
862
863            return "<div class='ilCreationFormSection'>" . $acc->getHTML() . "</div>";
864        }
865    }
866
867    /**
868     * Init object creation form
869     *
870     * @param	string	$a_new_type
871     * @return	ilPropertyFormGUI
872     */
873    protected function initCreateForm($a_new_type)
874    {
875        include_once("Services/Form/classes/class.ilPropertyFormGUI.php");
876        $form = new ilPropertyFormGUI();
877        $form->setTarget("_top");
878        $form->setFormAction($this->ctrl->getFormAction($this, "save"));
879        $form->setTitle($this->lng->txt($a_new_type . "_new"));
880
881        // title
882        $ti = new ilTextInputGUI($this->lng->txt("title"), "title");
883        $ti->setSize(min(40, ilObject::TITLE_LENGTH));
884        $ti->setMaxLength(ilObject::TITLE_LENGTH);
885        $ti->setRequired(true);
886        $form->addItem($ti);
887
888        // description
889        $ta = new ilTextAreaInputGUI($this->lng->txt("description"), "desc");
890        $ta->setCols(40);
891        $ta->setRows(2);
892        $form->addItem($ta);
893
894        $form = $this->initDidacticTemplate($form);
895
896        $form->addCommandButton("save", $this->lng->txt($a_new_type . "_add"));
897        $form->addCommandButton("cancel", $this->lng->txt("cancel"));
898
899        return $form;
900    }
901
902    /**
903     * Show didactic template types
904     * @param ilPropertyFormGUI $form
905     * @return ilPropertyFormGUI $form
906     */
907    protected function initDidacticTemplate(ilPropertyFormGUI $form)
908    {
909        $lng = $this->lng;
910
911        $lng->loadLanguageModule('didactic');
912        $existing_exclusive = false;
913        $options = [];
914        $options['dtpl_0'] = array($this->lng->txt('didactic_default_type'),
915            sprintf(
916                $this->lng->txt('didactic_default_type_info'),
917                $this->lng->txt('objs_' . $this->type)
918            ));
919
920        include_once './Services/DidacticTemplate/classes/class.ilDidacticTemplateSettings.php';
921        $templates = ilDidacticTemplateSettings::getInstanceByObjectType($this->type)->getTemplates();
922        if ($templates) {
923            foreach ($templates as $template) {
924                if ($template->isEffective($_GET["ref_id"])) {
925                    $options["dtpl_" . $template->getId()] = array(
926                        $template->getPresentationTitle(),
927                        $template->getPresentationDescription()
928                    );
929
930                    if ($template->isExclusive()) {
931                        $existing_exclusive = true;
932                    }
933                }
934            }
935        }
936
937        $this->addDidacticTemplateOptions($options);
938
939        if (sizeof($options) > 1) {
940            $type = new ilRadioGroupInputGUI(
941                $this->lng->txt('type'),
942                'didactic_type'
943            );
944            // workaround for containers in edit mode
945            if (!$this->getCreationMode()) {
946                include_once './Services/DidacticTemplate/classes/class.ilDidacticTemplateObjSettings.php';
947                $value = 'dtpl_' . ilDidacticTemplateObjSettings::lookupTemplateId($this->object->getRefId());
948
949                $type->setValue($value);
950
951                if (!in_array($value, array_keys($options)) || ($existing_exclusive && $value == "dtpl_0")) {
952                    //add or rename actual value to not avaiable
953                    $options[$value] = array($this->lng->txt('not_available'));
954                }
955            } else {
956                if ($existing_exclusive) {
957                    //if an exclusive template exists use the second template as default value
958                    $keys = array_keys($options);
959                    $type->setValue($keys[1]);
960                } else {
961                    $type->setValue('dtpl_0');
962                }
963            }
964            $form->addItem($type);
965
966            foreach ($options as $id => $data) {
967                $option = new ilRadioOption($data[0], $id, $data[1]);
968
969                if ($existing_exclusive && $id == 'dtpl_0') {
970                    //set default disabled if an exclusive template exists
971                    $option->setDisabled(true);
972                }
973
974                $type->addOption($option);
975            }
976        }
977
978        return $form;
979    }
980
981    /**
982     * Add custom templates
983     *
984     * @param array $a_options
985     */
986    protected function addDidacticTemplateOptions(array &$a_options)
987    {
988    }
989
990    /**
991     * cancel create action and go back to repository parent
992     */
993    public function cancelCreation()
994    {
995        $ilCtrl = $this->ctrl;
996
997        $ilCtrl->redirectByClass("ilrepositorygui", "frameset");
998    }
999
1000    /**
1001    * save object
1002    *
1003    * @access	public
1004    */
1005    public function saveObject()
1006    {
1007        $objDefinition = $this->objDefinition;
1008        $tpl = $this->tpl;
1009        $ilErr = $this->ilErr;
1010
1011        $new_type = $_REQUEST["new_type"];
1012
1013        // create permission is already checked in createObject. This check here is done to prevent hacking attempts
1014        if (!$this->checkPermissionBool("create", "", $new_type)) {
1015            $ilErr->raiseError($this->lng->txt("no_create_permission"), $ilErr->MESSAGE);
1016        }
1017
1018        $this->lng->loadLanguageModule($new_type);
1019        $this->ctrl->setParameter($this, "new_type", $new_type);
1020
1021        $form = $this->initCreateForm($new_type);
1022        if ($form->checkInput()) {
1023            $this->ctrl->setParameter($this, "new_type", "");
1024
1025            // create instance
1026            $class_name = "ilObj" . $objDefinition->getClassName($new_type);
1027            $location = $objDefinition->getLocation($new_type);
1028            include_once($location . "/class." . $class_name . ".php");
1029            $newObj = new $class_name();
1030            $newObj->setType($new_type);
1031            $newObj->setTitle($form->getInput("title"));
1032            $newObj->setDescription($form->getInput("desc"));
1033            $newObj->create();
1034
1035            $this->putObjectInTree($newObj);
1036
1037            // apply didactic template?
1038            $dtpl = $this->getDidacticTemplateVar("dtpl");
1039            if ($dtpl) {
1040                $newObj->applyDidacticTemplate($dtpl);
1041            }
1042
1043            // auto rating
1044            $this->handleAutoRating($newObj);
1045
1046            // additional paramters are added to afterSave()
1047            $args = func_get_args();
1048            if ($args) {
1049                $this->afterSave($newObj, $args);
1050            } else {
1051                $this->afterSave($newObj);
1052            }
1053            return;
1054        }
1055
1056        // display only this form to correct input
1057        $form->setValuesByPost();
1058        $tpl->setContent($form->getHtml());
1059    }
1060
1061    /**
1062     * Get didactic template setting from creation screen
1063     *
1064     * @param string $a_type
1065     * @return string
1066     */
1067    public function getDidacticTemplateVar($a_type)
1068    {
1069        $tpl = $_POST["didactic_type"];
1070        if ($tpl && substr($tpl, 0, strlen($a_type) + 1) == $a_type . "_") {
1071            return (int) substr($tpl, strlen($a_type) + 1);
1072        }
1073        return 0;
1074    }
1075
1076    /**
1077     * Add object to tree at given position
1078     *
1079     * @param ilObject $a_obj
1080     * @param int $a_parent_node_id
1081     */
1082    public function putObjectInTree(ilObject $a_obj, $a_parent_node_id = null)
1083    {
1084        $rbacreview = $this->rbacreview;
1085        $ilUser = $this->user;
1086        $objDefinition = $this->objDefinition;
1087
1088        if (!$a_parent_node_id) {
1089            $a_parent_node_id = $_GET["ref_id"];
1090        }
1091
1092        // add new object to custom parent container
1093        if ((int) $_REQUEST["crtptrefid"]) {
1094            $a_parent_node_id = (int) $_REQUEST["crtptrefid"];
1095        }
1096
1097        $a_obj->createReference();
1098        $a_obj->putInTree($a_parent_node_id);
1099        $a_obj->setPermissions($a_parent_node_id);
1100
1101        $this->obj_id = $a_obj->getId();
1102        $this->ref_id = $a_obj->getRefId();
1103
1104        // BEGIN ChangeEvent: Record save object.
1105        require_once('Services/Tracking/classes/class.ilChangeEvent.php');
1106        ilChangeEvent::_recordWriteEvent($this->obj_id, $ilUser->getId(), 'create');
1107        // END ChangeEvent: Record save object.
1108
1109        // rbac log
1110        include_once "Services/AccessControl/classes/class.ilRbacLog.php";
1111        $rbac_log_roles = $rbacreview->getParentRoleIds($this->ref_id, false);
1112        $rbac_log = ilRbacLog::gatherFaPa($this->ref_id, array_keys($rbac_log_roles), true);
1113        ilRbacLog::add(ilRbacLog::CREATE_OBJECT, $this->ref_id, $rbac_log);
1114
1115        // use forced callback after object creation
1116        if ($_REQUEST["crtcb"]) {
1117            $callback_type = ilObject::_lookupType((int) $_REQUEST["crtcb"], true);
1118            $class_name = "ilObj" . $objDefinition->getClassName($callback_type) . "GUI";
1119            $location = $objDefinition->getLocation($callback_type);
1120            include_once($location . "/class." . $class_name . ".php");
1121            if (in_array(strtolower($class_name), array("ilobjitemgroupgui"))) {
1122                $callback_obj = new $class_name((int) $_REQUEST["crtcb"]);
1123            } else {
1124                // #10368
1125                $callback_obj = new $class_name(null, (int) $_REQUEST["crtcb"], true, false);
1126            }
1127            $callback_obj->afterSaveCallback($a_obj);
1128        }
1129    }
1130
1131    /**
1132     * Post (successful) object creation hook
1133     *
1134     * @param ilObject $a_new_object
1135     */
1136    protected function afterSave(ilObject $a_new_object)
1137    {
1138        ilUtil::sendSuccess($this->lng->txt("object_added"), true);
1139        $this->ctrl->returnToParent($this);
1140    }
1141
1142    /**
1143     * edit object
1144     *
1145     * @access	public
1146     */
1147    public function editObject()
1148    {
1149        $tpl = $this->tpl;
1150        $ilTabs = $this->tabs_gui;
1151        $ilErr = $this->ilErr;
1152
1153        if (!$this->checkPermissionBool("write")) {
1154            $ilErr->raiseError($this->lng->txt("msg_no_perm_write"), $ilErr->MESSAGE);
1155        }
1156
1157        $ilTabs->activateTab("settings");
1158
1159        $form = $this->initEditForm();
1160        $values = $this->getEditFormValues();
1161        if ($values) {
1162            $form->setValuesByArray($values);
1163        }
1164
1165        $this->addExternalEditFormCustom($form);
1166
1167        $tpl->setContent($form->getHTML());
1168    }
1169
1170    public function addExternalEditFormCustom(ilPropertyFormGUI $a_form)
1171    {
1172        // has to be done AFTER setValuesByArray() ...
1173    }
1174
1175    /**
1176     * Init object edit form
1177     *
1178     * @return ilPropertyFormGUI
1179     */
1180    protected function initEditForm()
1181    {
1182        $lng = $this->lng;
1183        $ilCtrl = $this->ctrl;
1184
1185        $lng->loadLanguageModule($this->object->getType());
1186
1187        include_once("Services/Form/classes/class.ilPropertyFormGUI.php");
1188        $form = new ilPropertyFormGUI();
1189        $form->setFormAction($this->ctrl->getFormAction($this, "update"));
1190        $form->setTitle($this->lng->txt($this->object->getType() . "_edit"));
1191
1192        // title
1193        $ti = new ilTextInputGUI($this->lng->txt("title"), "title");
1194        $ti->setSize(min(40, ilObject::TITLE_LENGTH));
1195        $ti->setMaxLength(ilObject::TITLE_LENGTH);
1196        $ti->setRequired(true);
1197        $form->addItem($ti);
1198
1199        // description
1200        $ta = new ilTextAreaInputGUI($this->lng->txt("description"), "desc");
1201        $ta->setCols(40);
1202        $ta->setRows(2);
1203        $form->addItem($ta);
1204
1205        $this->initEditCustomForm($form);
1206
1207        $form->addCommandButton("update", $this->lng->txt("save"));
1208        //$this->form->addCommandButton("cancelUpdate", $lng->txt("cancel"));
1209
1210        return $form;
1211    }
1212
1213    /**
1214     * Add custom fields to update form
1215     *
1216     * @param	ilPropertyFormGUI	$a_form
1217     */
1218    protected function initEditCustomForm(ilPropertyFormGUI $a_form)
1219    {
1220    }
1221
1222    /**
1223     * Get values for edit form
1224     *
1225     * @return array
1226     */
1227    protected function getEditFormValues()
1228    {
1229        $values["title"] = $this->object->getTitle();
1230        $values["desc"] = $this->object->getLongDescription();
1231        $this->getEditFormCustomValues($values);
1232        return $values;
1233    }
1234
1235    /**
1236     * Add values to custom edit fields
1237     *
1238     * @param	array	$a_values
1239     */
1240    protected function getEditFormCustomValues(array &$a_values)
1241    {
1242    }
1243
1244    /**
1245     * updates object entry in object_data
1246     */
1247    public function updateObject()
1248    {
1249        $ilTabs = $this->tabs_gui;
1250        $tpl = $this->tpl;
1251        $ilErr = $this->ilErr;
1252
1253        if (!$this->checkPermissionBool("write")) {
1254            $ilErr->raiseError($this->lng->txt("permission_denied"), $ilErr->MESSAGE);
1255        }
1256
1257        $form = $this->initEditForm();
1258        if ($form->checkInput() &&
1259            $this->validateCustom($form)) {
1260            $this->object->setTitle($form->getInput("title"));
1261            $this->object->setDescription($form->getInput("desc"));
1262            $this->updateCustom($form);
1263            $this->object->update();
1264
1265            $this->afterUpdate();
1266            return;
1267        }
1268
1269        // display form again to correct errors
1270        $ilTabs->activateTab("settings");
1271        $form->setValuesByPost();
1272        $tpl->setContent($form->getHtml());
1273    }
1274
1275    /**
1276     * Validate custom values (if not possible with checkInput())
1277     *
1278     * @param ilPropertyFormGUI $a_form
1279     * @return boolean
1280     */
1281    protected function validateCustom(ilPropertyFormGUI $a_form)
1282    {
1283        return true;
1284    }
1285
1286    /**
1287     * Insert custom update form values into object
1288     *
1289     * @param	ilPropertyFormGUI	$a_form
1290     */
1291    protected function updateCustom(ilPropertyFormGUI $a_form)
1292    {
1293    }
1294
1295    /**
1296     * Post (successful) object update hook
1297     */
1298    protected function afterUpdate()
1299    {
1300        ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1301        $this->ctrl->redirect($this, "edit");
1302    }
1303
1304    /**
1305     * Init object import form
1306     *
1307     * @param	string	new type
1308     * @return	ilPropertyFormGUI
1309     */
1310    protected function initImportForm($a_new_type)
1311    {
1312        include_once("Services/Form/classes/class.ilPropertyFormGUI.php");
1313        $form = new ilPropertyFormGUI();
1314        $form->setTarget("_top");
1315        $form->setFormAction($this->ctrl->getFormAction($this, "importFile"));
1316        $form->setTitle($this->lng->txt($a_new_type . "_import"));
1317
1318        include_once("./Services/Form/classes/class.ilFileInputGUI.php");
1319        $fi = new ilFileInputGUI($this->lng->txt("import_file"), "importfile");
1320        $fi->setSuffixes(array("zip"));
1321        $fi->setRequired(true);
1322        $form->addItem($fi);
1323
1324        $form->addCommandButton("importFile", $this->lng->txt("import"));
1325        $form->addCommandButton("cancel", $this->lng->txt("cancel"));
1326
1327        return $form;
1328    }
1329
1330    /**
1331     * Import
1332     */
1333    protected function importFileObject($parent_id = null, $a_catch_errors = true)
1334    {
1335        $objDefinition = $this->objDefinition;
1336        $tpl = $this->tpl;
1337        $ilErr = $this->ilErr;
1338
1339        if (!$parent_id) {
1340            $parent_id = $_GET["ref_id"];
1341        }
1342        $new_type = $_REQUEST["new_type"];
1343
1344        // create permission is already checked in createObject. This check here is done to prevent hacking attempts
1345        if (!$this->checkPermissionBool("create", "", $new_type)) {
1346            $ilErr->raiseError($this->lng->txt("no_create_permission"));
1347        }
1348
1349        $this->lng->loadLanguageModule($new_type);
1350        $this->ctrl->setParameter($this, "new_type", $new_type);
1351
1352        $form = $this->initImportForm($new_type);
1353        if ($form->checkInput()) {
1354            // :todo: make some check on manifest file
1355
1356            if ($objDefinition->isContainer($new_type)) {
1357                include_once './Services/Export/classes/class.ilImportContainer.php';
1358                $imp = new ilImportContainer((int) $parent_id);
1359            } else {
1360                include_once("./Services/Export/classes/class.ilImport.php");
1361                $imp = new ilImport((int) $parent_id);
1362            }
1363
1364            try {
1365                $new_id = $imp->importObject(
1366                    null,
1367                    $_FILES["importfile"]["tmp_name"],
1368                    $_FILES["importfile"]["name"],
1369                    $new_type
1370                );
1371            } catch (ilException $e) {
1372                $this->tmp_import_dir = $imp->getTemporaryImportDir();
1373                if (!$a_catch_errors) {
1374                    throw $e;
1375                }
1376                // display message and form again
1377                ilUtil::sendFailure($this->lng->txt("obj_import_file_error") . " <br />" . $e->getMessage());
1378                $form->setValuesByPost();
1379                $tpl->setContent($form->getHtml());
1380                return;
1381            }
1382
1383            if ($new_id > 0) {
1384                $this->ctrl->setParameter($this, "new_type", "");
1385
1386                $newObj = ilObjectFactory::getInstanceByObjId($new_id);
1387
1388                // put new object id into tree - already done in import for containers
1389                if (!$objDefinition->isContainer($new_type)) {
1390                    $this->putObjectInTree($newObj);
1391                }
1392
1393                $this->afterImport($newObj);
1394            }
1395            // import failed
1396            else {
1397                if ($objDefinition->isContainer($new_type)) {
1398                    ilUtil::sendFailure($this->lng->txt("container_import_zip_file_invalid"));
1399                } else {
1400                    // not enough information here...
1401                    return;
1402                }
1403            }
1404        }
1405
1406        // display form to correct errors
1407        $form->setValuesByPost();
1408        $tpl->setContent($form->getHtml());
1409    }
1410
1411    /**
1412     * Post (successful) object import hook
1413     *
1414     * @param ilObject $a_new_object
1415     */
1416    protected function afterImport(ilObject $a_new_object)
1417    {
1418        ilUtil::sendSuccess($this->lng->txt("object_added"), true);
1419        $this->ctrl->returnToParent($this);
1420    }
1421
1422    /**
1423    * get form action for command (command is method name without "Object", e.g. "perm")
1424    * @param	string		$a_cmd			command
1425    * @param	string		$a_formaction	default formaction (is returned, if no special
1426    *										formaction was set)
1427    * @access	public
1428    * @return	string
1429    */
1430    public function getFormAction($a_cmd, $a_formaction = "")
1431    {
1432        if ($this->formaction[$a_cmd] != "") {
1433            return $this->formaction[$a_cmd];
1434        } else {
1435            return $a_formaction;
1436        }
1437    }
1438
1439    /**
1440    * set specific form action for command
1441    *
1442    * @param	string		$a_cmd			command
1443    * @param	string		$a_formaction	default formaction (is returned, if no special
1444    *										formaction was set)
1445    * @access	public
1446    */
1447    protected function setFormAction($a_cmd, $a_formaction)
1448    {
1449        $this->formaction[$a_cmd] = $a_formaction;
1450    }
1451
1452    /**
1453    * get return location for command (command is method name without "Object", e.g. "perm")
1454    * @param	string		$a_cmd		command
1455    * @param	string		$a_location	default return location (is returned, if no special
1456    *									return location was set)
1457    * @access	public
1458    */
1459    protected function getReturnLocation($a_cmd, $a_location = "")
1460    {
1461        if ($this->return_location[$a_cmd] != "") {
1462            return $this->return_location[$a_cmd];
1463        } else {
1464            return $a_location;
1465        }
1466    }
1467
1468    /**
1469    * set specific return location for command
1470    * @param	string		$a_cmd		command
1471    * @param	string		$a_location	default return location (is returned, if no special
1472    *									return location was set)
1473    * @access	public
1474    */
1475    protected function setReturnLocation($a_cmd, $a_location)
1476    {
1477        //echo "-".$a_cmd."-".$a_location."-";
1478        $this->return_location[$a_cmd] = $a_location;
1479    }
1480
1481    /**
1482    * get target frame for command (command is method name without "Object", e.g. "perm")
1483    * @param	string		$a_cmd			command
1484    * @param	string		$a_target_frame	default target frame (is returned, if no special
1485    *										target frame was set)
1486    * @access	public
1487    */
1488    protected function getTargetFrame($a_cmd, $a_target_frame = "")
1489    {
1490        if ($this->target_frame[$a_cmd] != "") {
1491            return $this->target_frame[$a_cmd];
1492        } elseif (!empty($a_target_frame)) {
1493            return "target=\"" . $a_target_frame . "\"";
1494        } else {
1495            return;
1496        }
1497    }
1498
1499    /**
1500    * set specific target frame for command
1501    * @param	string		$a_cmd			command
1502    * @param	string		$a_target_frame	default target frame (is returned, if no special
1503    *										target frame was set)
1504    * @access	public
1505    */
1506    protected function setTargetFrame($a_cmd, $a_target_frame)
1507    {
1508        $this->target_frame[$a_cmd] = "target=\"" . $a_target_frame . "\"";
1509    }
1510
1511    // BEGIN Security: Hide objects which aren't accessible by the user.
1512    public function isVisible($a_ref_id, $a_type)
1513    {
1514        $visible = $this->checkPermissionBool("visible,read", "", "", $a_ref_id);
1515
1516        if ($visible && $a_type == 'crs') {
1517            $tree = $this->tree;
1518            if ($crs_id = $tree->checkForParentType($a_ref_id, 'crs')) {
1519                if (!$this->checkPermissionBool("write", "", "", $crs_id)) {
1520                    // Show only activated courses
1521                    $tmp_obj = &ilObjectFactory::getInstanceByRefId($crs_id, false);
1522
1523                    if (!$tmp_obj->isActivated()) {
1524                        unset($tmp_obj);
1525                        $visible = false;
1526                    }
1527                }
1528            }
1529        }
1530
1531        return $visible;
1532    }
1533    // END Security: Hide objects which aren't accessible by the user.
1534
1535    /**
1536    * list childs of current object
1537    *
1538    * @access	public
1539    */
1540    public function viewObject()
1541    {
1542        $tpl = $this->tpl;
1543        $ilErr = $this->ilErr;
1544
1545        if (!$this->checkPermissionBool("visible,read")) {
1546            $ilErr->raiseError($this->lng->txt("permission_denied"), $ilErr->MESSAGE);
1547        }
1548
1549        // BEGIN ChangeEvent: record read event.
1550        require_once('Services/Tracking/classes/class.ilChangeEvent.php');
1551        $ilUser = $this->user;
1552        ilChangeEvent::_recordReadEvent(
1553            $this->object->getType(),
1554            $this->object->getRefId(),
1555            $this->object->getId(),
1556            $ilUser->getId()
1557        );
1558        // END ChangeEvent: record read event.
1559
1560        include_once("./Services/Repository/classes/class.ilAdminSubItemsTableGUI.php");
1561        if (!$this->call_by_reference) {
1562            $this->ctrl->setParameter($this, "obj_id", $this->obj_id);
1563        }
1564        $itab = new ilAdminSubItemsTableGUI(
1565            $this,
1566            "view",
1567            $_GET["ref_id"],
1568            $this->checkPermissionBool('write')
1569        );
1570
1571        $tpl->setContent($itab->getHTML());
1572    }
1573
1574    /**
1575    * Display deletion confirmation screen.
1576    * Only for referenced objects. For user,role & rolt overwrite this function in the appropriate
1577    * Object folders classes (ilObjUserFolderGUI,ilObjRoleFolderGUI)
1578    *
1579    * @access	public
1580    */
1581    public function deleteObject($a_error = false)
1582    {
1583        $ilCtrl = $this->ctrl;
1584
1585        if ($_GET["item_ref_id"] != "") {
1586            $_POST["id"] = array($_GET["item_ref_id"]);
1587        }
1588
1589        if (is_array($_POST["id"])) {
1590            foreach ($_POST["id"] as $idx => $id) {
1591                $_POST["id"][$idx] = (int) $id;
1592            }
1593        }
1594
1595        // SAVE POST VALUES (get rid of this
1596        ilSession::set("saved_post", $_POST["id"]);
1597
1598        include_once("./Services/Repository/classes/class.ilRepUtilGUI.php");
1599        $ru = new ilRepUtilGUI($this);
1600        if (!$ru->showDeleteConfirmation($_POST["id"], $a_error)) {
1601            $ilCtrl->returnToParent($this);
1602        }
1603    }
1604
1605    /**
1606    * show possible subobjects (pulldown menu)
1607    *
1608    * @access	public
1609    */
1610    protected function showPossibleSubObjects()
1611    {
1612        if ($this->sub_objects == "") {
1613            $d = $this->objDefinition->getCreatableSubObjects($this->object->getType(), ilObjectDefinition::MODE_REPOSITORY, $this->ref_id);
1614        } else {
1615            $d = $this->sub_objects;
1616        }
1617
1618        $import = false;
1619
1620        if (count($d) > 0) {
1621            foreach ($d as $row) {
1622                $count = 0;
1623
1624                if ($row["max"] > 0) {
1625                    //how many elements are present?
1626                    for ($i = 0; $i < count($this->data["ctrl"]); $i++) {
1627                        if ($this->data["ctrl"][$i]["type"] == $row["name"]) {
1628                            $count++;
1629                        }
1630                    }
1631                }
1632
1633                if ($row["max"] == "" || $count < $row["max"]) {
1634                    $subobj[] = $row["name"];
1635                }
1636            }
1637        }
1638
1639        if (is_array($subobj)) {
1640
1641            //build form
1642            $opts = ilUtil::formSelect(12, "new_type", $subobj);
1643            $this->tpl->setCurrentBlock("add_object");
1644            $this->tpl->setVariable("SELECT_OBJTYPE", $opts);
1645            $this->tpl->setVariable("BTN_NAME", "create");
1646            $this->tpl->setVariable("TXT_ADD", $this->lng->txt("add"));
1647            $this->tpl->parseCurrentBlock();
1648        }
1649    }
1650
1651    /**
1652    * get a template blockfile
1653    * format: tpl.<objtype>_<command>.html
1654    *
1655    * @param	string	command
1656    * @param	string	object type definition
1657    * @access	public
1658    */
1659    final protected function getTemplateFile($a_cmd, $a_type = "")
1660    {
1661        mk();
1662        die("ilObjectGUI::getTemplateFile() is deprecated.");
1663    }
1664
1665    /**
1666    * get tabs
1667    * abstract method.
1668    * @abstract	overwrite in derived GUI class of your object type
1669    * @access	public
1670    * @param	object	instance of ilTabsGUI
1671    */
1672    protected function getTabs()
1673    {
1674        // please define your tabs here
1675    }
1676
1677    // PROTECTED
1678    protected function __showButton($a_cmd, $a_text, $a_target = '')
1679    {
1680        $ilToolbar = $this->toolbar;
1681
1682        $ilToolbar->addButton($a_text, $this->ctrl->getLinkTarget($this, $a_cmd), $a_target);
1683    }
1684
1685    protected function hitsperpageObject()
1686    {
1687        ilSession::set("tbl_limit", $_POST["hitsperpage"]);
1688        $_GET["limit"] = $_POST["hitsperpage"];
1689    }
1690
1691
1692    protected function &__initTableGUI()
1693    {
1694        include_once "./Services/Table/classes/class.ilTableGUI.php";
1695
1696        return new ilTableGUI(0, false);
1697    }
1698
1699    /**
1700     * standard implementation for tables
1701     * use 'from' variable use different initial setting of table
1702     *
1703     */
1704    protected function __setTableGUIBasicData(&$tbl, &$result_set, $a_from = "")
1705    {
1706        switch ($a_from) {
1707            case "clipboardObject":
1708                $offset = $_GET["offset"];
1709                $order = $_GET["sort_by"];
1710                $direction = $_GET["sort_order"];
1711                $tbl->disable("footer");
1712                break;
1713
1714            default:
1715                $offset = $_GET["offset"];
1716                $order = $_GET["sort_by"];
1717                $direction = $_GET["sort_order"];
1718                break;
1719        }
1720
1721        $tbl->setOrderColumn($order);
1722        $tbl->setOrderDirection($direction);
1723        $tbl->setOffset($offset);
1724        $tbl->setLimit($_GET["limit"]);
1725        $tbl->setFooter("tblfooter", $this->lng->txt("previous"), $this->lng->txt("next"));
1726        $tbl->setData($result_set);
1727    }
1728
1729    /**
1730    * redirects to (repository) view per ref id
1731    * usually to a container and usually used at
1732    * the end of a save/import method where the object gui
1733    * type (of the new object) doesn't match with the type
1734    * of the current $_GET["ref_id"] value
1735    *
1736    * @param	int		$a_ref_id		reference id
1737    */
1738    protected function redirectToRefId($a_ref_id, $a_cmd = "")
1739    {
1740        $obj_type = ilObject::_lookupType($a_ref_id, true);
1741        $class_name = $this->objDefinition->getClassName($obj_type);
1742        $class = strtolower("ilObj" . $class_name . "GUI");
1743        $this->ctrl->setParameterByClass("ilrepositorygui", "ref_id", $a_ref_id);
1744        $this->ctrl->redirectByClass(array("ilrepositorygui", $class), $a_cmd);
1745    }
1746
1747    // Object Cloning
1748    /**
1749     * Fill object clone template
1750     * This method can be called from any object GUI class that wants to offer object cloning.
1751     *
1752     * @access public
1753     * @param string template variable name that will be filled
1754     * @param string type of new object
1755     *
1756     */
1757    protected function fillCloneTemplate($a_tpl_varname, $a_type)
1758    {
1759        include_once './Services/Object/classes/class.ilObjectCopyGUI.php';
1760        $cp = new ilObjectCopyGUI($this);
1761        $cp->setType($a_type);
1762        $cp->setTarget($_GET['ref_id']);
1763        if ($a_tpl_varname) {
1764            $cp->showSourceSearch($a_tpl_varname);
1765        } else {
1766            return $cp->showSourceSearch(null);
1767        }
1768    }
1769
1770    /**
1771     * Clone single (not container object)
1772     * Method is overwritten in ilContainerGUI
1773     *
1774     * @access public
1775     */
1776    public function cloneAllObject()
1777    {
1778        include_once('./Services/Link/classes/class.ilLink.php');
1779        include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
1780
1781        $ilErr = $this->ilErr;
1782        $ilUser = $this->user;
1783
1784        $new_type = $_REQUEST['new_type'];
1785        if (!$this->checkPermissionBool("create", "", $new_type)) {
1786            $ilErr->raiseError($this->lng->txt('permission_denied'));
1787        }
1788        if (!(int) $_REQUEST['clone_source']) {
1789            ilUtil::sendFailure($this->lng->txt('select_one'));
1790            $this->createObject();
1791            return false;
1792        }
1793        if (!$this->checkPermissionBool("write", "", $new_type, (int) $_REQUEST['clone_source'])) {
1794            $ilErr->raiseError($this->lng->txt('permission_denied'));
1795        }
1796
1797        // Save wizard options
1798        $copy_id = ilCopyWizardOptions::_allocateCopyId();
1799        $wizard_options = ilCopyWizardOptions::_getInstance($copy_id);
1800        $wizard_options->saveOwner($ilUser->getId());
1801        $wizard_options->saveRoot((int) $_REQUEST['clone_source']);
1802
1803        $options = $_POST['cp_options'] ? $_POST['cp_options'] : array();
1804        foreach ($options as $source_id => $option) {
1805            $wizard_options->addEntry($source_id, $option);
1806        }
1807        $wizard_options->read();
1808
1809        $orig = ilObjectFactory::getInstanceByRefId((int) $_REQUEST['clone_source']);
1810        $new_obj = $orig->cloneObject((int) $_GET['ref_id'], $copy_id);
1811
1812        // Delete wizard options
1813        $wizard_options->deleteAll();
1814
1815        ilUtil::sendSuccess($this->lng->txt("object_duplicated"), true);
1816        ilUtil::redirect(ilLink::_getLink($new_obj->getRefId()));
1817    }
1818
1819
1820    /**
1821    * Get center column
1822    */
1823    protected function getCenterColumnHTML()
1824    {
1825        $ilCtrl = $this->ctrl;
1826
1827        include_once("Services/Block/classes/class.ilColumnGUI.php");
1828
1829        $obj_id = ilObject::_lookupObjId($this->object->getRefId());
1830        $obj_type = ilObject::_lookupType($obj_id);
1831
1832        if ($ilCtrl->getNextClass() != "ilcolumngui") {
1833            // normal command processing
1834            return $this->getContent();
1835        } else {
1836            if (!$ilCtrl->isAsynch()) {
1837                //if ($column_gui->getScreenMode() != IL_SCREEN_SIDE)
1838                if (ilColumnGUI::getScreenMode() != IL_SCREEN_SIDE) {
1839                    // right column wants center
1840                    if (ilColumnGUI::getCmdSide() == IL_COL_RIGHT) {
1841                        $column_gui = new ilColumnGUI($obj_type, IL_COL_RIGHT);
1842                        $this->setColumnSettings($column_gui);
1843                        $this->html = $ilCtrl->forwardCommand($column_gui);
1844                    }
1845                    // left column wants center
1846                    if (ilColumnGUI::getCmdSide() == IL_COL_LEFT) {
1847                        $column_gui = new ilColumnGUI($obj_type, IL_COL_LEFT);
1848                        $this->setColumnSettings($column_gui);
1849                        $this->html = $ilCtrl->forwardCommand($column_gui);
1850                    }
1851                } else {
1852                    // normal command processing
1853                    return $this->getContent();
1854                }
1855            }
1856        }
1857    }
1858
1859    /**
1860    * Display right column
1861    */
1862    protected function getRightColumnHTML()
1863    {
1864        $ilUser = $this->user;
1865        $lng = $this->lng;
1866        $ilCtrl = $this->ctrl;
1867
1868        $obj_id = ilObject::_lookupObjId($this->object->getRefId());
1869        $obj_type = ilObject::_lookupType($obj_id);
1870
1871        include_once("Services/Block/classes/class.ilColumnGUI.php");
1872        $column_gui = new ilColumnGUI($obj_type, IL_COL_RIGHT);
1873
1874        if ($column_gui->getScreenMode() == IL_SCREEN_FULL) {
1875            return "";
1876        }
1877
1878        $this->setColumnSettings($column_gui);
1879
1880        if ($ilCtrl->getNextClass() == "ilcolumngui" &&
1881            $column_gui->getCmdSide() == IL_COL_RIGHT &&
1882            $column_gui->getScreenMode() == IL_SCREEN_SIDE) {
1883            $html = $ilCtrl->forwardCommand($column_gui);
1884        } else {
1885            if (!$ilCtrl->isAsynch()) {
1886                $html = $ilCtrl->getHTML($column_gui);
1887            }
1888        }
1889
1890        return $html;
1891    }
1892
1893    /**
1894    * May be overwritten in subclasses.
1895    */
1896    protected function setColumnSettings(ilColumnGUI $column_gui)
1897    {
1898        $column_gui->setRepositoryMode(true);
1899        $column_gui->setEnableEdit(false);
1900        if ($this->checkPermissionBool("write")) {
1901            $column_gui->setEnableEdit(true);
1902        }
1903    }
1904
1905    /**
1906     * Check permission and redirect on error
1907     *
1908     * @param string $a_perm
1909     * @param string $a_cmd
1910     * @param string $a_type
1911     * @param int $a_ref_id
1912     * @throws ilObjectException
1913     * @return bool
1914     */
1915    protected function checkPermission($a_perm, $a_cmd = "", $a_type = "", $a_ref_id = null)
1916    {
1917        if (!$this->checkPermissionBool($a_perm, $a_cmd, $a_type, $a_ref_id)) {
1918            if (!is_int(strpos($_SERVER["PHP_SELF"], "goto.php"))) {
1919                // create: redirect to parent
1920                if ($a_perm == "create") {
1921                    if (!$a_ref_id) {
1922                        $a_ref_id = $_GET["ref_id"];
1923                    }
1924                    $type = ilObject::_lookupType($a_ref_id, true);
1925                } else {
1926                    // does this make sense?
1927                    if (!is_object($this->object)) {
1928                        return;
1929                    }
1930                    if (!$a_ref_id) {
1931                        $a_ref_id = $this->object->getRefId();
1932                    }
1933                    $type = $this->object->getType();
1934                }
1935
1936                ilSession::clear("il_rep_ref_id");
1937
1938                include_once "Services/Object/exceptions/class.ilObjectException.php";
1939                throw new ilObjectException($this->lng->txt("permission_denied"));
1940
1941            /*
1942            ilUtil::sendFailure($this->lng->txt("permission_denied"), true);
1943            ilUtil::redirect("goto.php?target=".$type."_".$a_ref_id);
1944            */
1945            }
1946            // we should never be here
1947            else {
1948                die("Permission Denied.");
1949            }
1950        }
1951    }
1952
1953    /**
1954     * Check permission
1955     *
1956     * @param string $a_perm
1957     * @param string $a_cmd
1958     * @param string $a_type
1959     * @param int $a_ref_id
1960     * @return bool
1961     */
1962    protected function checkPermissionBool($a_perm, $a_cmd = "", $a_type = "", $a_ref_id = null)
1963    {
1964        $ilAccess = $this->access;
1965
1966        if ($a_perm == "create") {
1967            if (!$a_ref_id) {
1968                $a_ref_id = $_GET["ref_id"];
1969            }
1970            return $ilAccess->checkAccess($a_perm . "_" . $a_type, $a_cmd, $a_ref_id);
1971        } else {
1972            // does this make sense?
1973            if (!is_object($this->object)) {
1974                return false;
1975            }
1976            if (!$a_ref_id) {
1977                $a_ref_id = $this->object->getRefId();
1978            }
1979            return $ilAccess->checkAccess($a_perm, $a_cmd, $a_ref_id);
1980        }
1981    }
1982
1983    /**
1984     * Goto repository root
1985     *
1986     * @param
1987     * @return
1988     */
1989    public static function _gotoRepositoryRoot($a_raise_error = false)
1990    {
1991        global $DIC;
1992
1993        $ilAccess = $DIC->access();
1994        $ilErr = $DIC["ilErr"];
1995        $lng = $DIC->language();
1996
1997        if ($ilAccess->checkAccess("read", "", ROOT_FOLDER_ID)) {
1998            $_GET["cmd"] = "frameset";
1999            $_GET["target"] = "";
2000            $_GET["ref_id"] = ROOT_FOLDER_ID;
2001            $_GET["baseClass"] = "ilRepositoryGUI";
2002            include("ilias.php");
2003            exit;
2004        }
2005
2006        if ($a_raise_error) {
2007            $ilErr->raiseError($lng->txt("msg_no_perm_read"), $ilErr->FATAL);
2008        }
2009    }
2010
2011    /**
2012     * Goto repository root
2013     *
2014     * @param
2015     * @return
2016     */
2017    public static function _gotoRepositoryNode($a_ref_id, $a_cmd = "frameset")
2018    {
2019        global $DIC;
2020
2021        $ilAccess = $DIC->access();
2022        $ilErr = $DIC["ilErr"];
2023
2024        $_GET["cmd"] = $a_cmd;
2025        $_GET["target"] = "";
2026        $_GET["ref_id"] = $a_ref_id;
2027        $_GET["baseClass"] = "ilRepositoryGUI";
2028        include("ilias.php");
2029        exit;
2030    }
2031
2032    /**
2033     * Enables the file upload into this object by dropping files.
2034     */
2035    protected function enableDragDropFileUpload()
2036    {
2037        include_once("./Services/FileUpload/classes/class.ilFileUploadGUI.php");
2038        ilFileUploadGUI::initFileUpload();
2039
2040        $this->tpl->enableDragDropFileUpload($this->ref_id);
2041    }
2042
2043    /**
2044     * Activate rating automatically if parent container setting
2045     *
2046     * @param ilObject $a_new_obj
2047     */
2048    protected function handleAutoRating(ilObject $a_new_obj)
2049    {
2050        if (ilObject::hasAutoRating($a_new_obj->getType(), $a_new_obj->getRefId()) &&
2051            method_exists($a_new_obj, "setRating")) {
2052            $a_new_obj->setRating(true);
2053            $a_new_obj->update();
2054        }
2055    }
2056
2057    /**
2058     * show edit section of custom icons for container
2059     *
2060     */
2061    protected function showCustomIconsEditing($a_input_colspan = 1, ilPropertyFormGUI $a_form = null, $a_as_section = true)
2062    {
2063        if ($this->settings->get("custom_icons")) {
2064            if ($a_form) {
2065                global $DIC;
2066                /** @var \ilObjectCustomIconFactory  $customIconFactory */
2067                $customIconFactory = $DIC['object.customicons.factory'];
2068
2069                $customIcon = $customIconFactory->getByObjId($this->object->getId(), $this->object->getType());
2070
2071                if ($a_as_section) {
2072                    $title = new ilFormSectionHeaderGUI();
2073                    $title->setTitle($this->lng->txt("icon_settings"));
2074                } else {
2075                    $title = new ilCustomInputGUI($this->lng->txt("icon_settings"), "");
2076                }
2077                $a_form->addItem($title);
2078
2079                $caption = $this->lng->txt("cont_custom_icon");
2080                $icon = new ilImageFileInputGUI($caption, "cont_icon");
2081
2082                $icon->setSuffixes($customIcon->getSupportedFileExtensions());
2083                $icon->setUseCache(false);
2084                if ($customIcon->exists()) {
2085                    $icon->setImage($customIcon->getFullPath());
2086                } else {
2087                    $icon->setImage('');
2088                }
2089                if ($a_as_section) {
2090                    $a_form->addItem($icon);
2091                } else {
2092                    $title->addSubItem($icon);
2093                }
2094            }
2095        }
2096    }
2097
2098    /**
2099     * Redirect after creation, see https://docu.ilias.de/goto_docu_wiki_wpage_5035_1357.html
2100     *
2101     * Should be overwritten and redirect to settings screen.
2102     */
2103    public function redirectAfterCreation()
2104    {
2105        $ctrl = $this->ctrl;
2106        $link = ilLink::_getLink($this->object->getRefId());
2107        $ctrl->redirectToURL($link);
2108    }
2109}
2110