ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilObjStudyProgrammeTreeGUI.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
29 {
31  protected ilCtrl $ctrl;
34  protected ilLanguage $lng;
36  protected Ilias $ilias;
37  protected ilSetting $ilSetting;
38  protected ilTree $ilTree;
42 
46  protected string $modal_id;
48 
52  protected int $ref_id;
55 
56  public function __construct(
58  ilCtrl $ilCtrl,
59  ilAccess $ilAccess,
60  ilToolbarGUI $ilToolbar,
61  ilLanguage $lng,
62  ilComponentLogger $ilLog,
63  ILIAS $ilias,
64  ilSetting $ilSetting,
65  ilTree $ilTree,
66  ilRbacAdmin $rbacadmin,
67  ILIAS\HTTP\Wrapper\WrapperFactory $http_wrapper,
68  ILIAS\Refinery\Factory $refinery
69  ) {
70  $this->tpl = $tpl;
71  $this->ctrl = $ilCtrl;
72  $this->access = $ilAccess;
73  $this->toolbar = $ilToolbar;
74  $this->log = $ilLog;
75  $this->ilias = $ilias;
76  $this->lng = $lng;
77  $this->ilSetting = $ilSetting;
78  $this->ilTree = $ilTree;
79  $this->rbacadmin = $rbacadmin;
80  $this->http_wrapper = $http_wrapper;
81  $this->refinery = $refinery;
82 
83  $this->modal_id = "tree_modal";
84  $this->async_output_handler = new ilAsyncOutputHandler();
85 
86  $lng->loadLanguageModule("prg");
87  }
88 
89  public function setRefId(int $ref_id): void
90  {
91  $this->ref_id = $ref_id;
92  }
93 
98  protected function initTree(): void
99  {
100  $this->tree = new ilObjStudyProgrammeTreeExplorerGUI($this->ref_id, $this->modal_id, "prg_tree", $this, 'view');
101 
102  $js_url = rawurldecode($this->ctrl->getLinkTarget($this, 'saveTreeOrder', '', true));
103  $this->tree->addJsConf('save_tree_url', $js_url);
104  $this->tree->addJsConf('save_button_id', 'save_order_button');
105  $this->tree->addJsConf('cancel_button_id', 'cancel_order_button');
106  }
107 
114  public function executeCommand(): void
115  {
116  $this->initTree();
117  $cmd = $this->ctrl->getCmd();
118 
119  $this->getToolbar();
120 
121  if ($cmd === "" || $cmd === null) {
122  $cmd = "view";
123  }
124 
125  // handles tree commands ("openNode", "closeNode", "getNodeAsync")
126  if ($this->tree->handleCommand()) {
127  exit();
128  }
129 
130  switch ($cmd) {
131  case "view":
132  case "create":
133  case "save":
134  case "cancel":
135  case "delete":
136  case "confirmedDelete":
137  case "cancelDelete":
138  case "getContainerSelectionExplorer":
139  case "saveTreeOrder":
140  case "createNewLeaf":
141 
142  $content = $this->$cmd();
143  break;
144  default:
145  throw new ilException("ilObjStudyProgrammeTreeGUI: " .
146  "Command not supported: $cmd");
147  }
148 
150  }
151 
155  protected function view(): string
156  {
157  $output = $this->tree->getHTML();
158  $output .= $this->initAsyncUIElements();
159 
160  return $output;
161  }
162 
166  protected function cancel(): string
167  {
169  }
170 
177  protected function saveTreeOrder(): string
178  {
179  $this->checkAccessOrFail('write');
180 
181  $tree = "";
182  if ($this->http_wrapper->post()->has("tree")) {
183  $tree = $this->http_wrapper->post()->retrieve("tree", $this->refinery->kindlyTo()->string());
184  }
185  $treeAsJson = ilUtil::stripSlashes($tree);
186  $treeData = json_decode($treeAsJson, false, 512, JSON_THROW_ON_ERROR);
187 
188  if (!is_array($treeData) || [] === $treeData) {
189  throw new ilStudyProgrammeTreeException("There is no tree data to save!");
190  }
191 
192  // saves order recursive
193  $this->storeTreeOrder($treeData);
194 
196  ['success' => true, 'message' => $this->lng->txt('prg_saved_order_successful')]
197  );
198  }
199 
203  protected function storeTreeOrder(
204  array $nodes,
205  ilContainerSorting $container_sorting = null,
206  int $parent_ref_id = null
207  ): void {
208  $sorting_position = array();
209  $position_count = 10;
210 
211  $ref_id = $parent_ref_id;
212  if (is_null($ref_id)) {
213  $ref_id = $this->ref_id;
214  }
215 
217  $parent_node = ilObjectFactoryWrapper::singleton()->getInstanceByRefId($ref_id);
218 
219  if (is_null($container_sorting)) {
220  $container_sorting = ilContainerSorting::_getInstance(ilObject::_lookupObjectId($this->ref_id));
221  }
222 
223  foreach ($nodes as $node) {
224  // get ref_id from json
225  $id = $node->id;
226  $id = substr($id, strrpos($id, "_") + 1);
227 
228  $sorting_position[$id] = $position_count;
229  $position_count += 10;
230 
231  $node_obj = ilObjectFactoryWrapper::singleton()->getInstanceByRefId((int) $id);
232  if ($node_obj instanceof ilObjStudyProgramme) {
233  $node_obj->moveTo($parent_node);
234  } else {
235  // TODO: implement a method on ilObjStudyProgramme to move leafs
236  $this->ilTree->moveTree($node_obj->getRefId(), $parent_node->getRefId());
237  $this->rbacadmin->adjustMovedObjectPermissions($node_obj->getRefId(), $parent_node->getRefId());
238  }
239 
240  // recursion if there are children
241  if (isset($node->children)) {
242  $this->storeTreeOrder(
243  $node->children,
245  (int) $id
246  );
247  }
248  }
249  $container_sorting->savePost($sorting_position);
250  }
251 
258  protected function createNewLeaf(): string
259  {
260  $this->checkAccessOrFail('create', $this->http_wrapper->post()->retrieve("parent_id", $this->refinery->kindlyTo()->int()));
261 
262  if (
263  $this->http_wrapper->post()->has("target_id") &&
264  $this->http_wrapper->post()->has("type") &&
265  $this->http_wrapper->post()->has("parent_id")
266  ) {
267  $target_id = $this->http_wrapper->post()->retrieve("target_id", $this->refinery->kindlyTo()->int());
268  $parent_id = $this->http_wrapper->post()->retrieve("parent_id", $this->refinery->kindlyTo()->int());
269 
270  // TODO: more generic way for implementing different type of leafs
271  $course_ref = new ilObjCourseReference();
272  $course_ref->setTitleType(ilContainerReference::TITLE_TYPE_REUSE);
273  $course_ref->setTargetRefId($target_id);
274 
275  $course_ref->create();
276  $course_ref->createReference();
277 
278  $course_ref->putInTree($parent_id);
279 
280  // This is how it's done in ILIAS. If you set the target ID before the creation, it won't work
281  $course_ref->setTargetId(ilObject::_lookupObjectId($target_id));
282  $course_ref->update();
283  }
284 
286  ['success' => true, 'message' => $this->lng->txt('prg_added_course_ref_successful')]
287  );
288  }
289 
290 
297  protected function getContainerSelectionExplorer(bool $convert_to_string = true)
298  {
299  $create_leaf_form = new ilAsyncContainerSelectionExplorer(
300  rawurldecode($this->ctrl->getLinkTarget($this, 'createNewLeaf', '', true)),
301  $this->refinery,
302  $this->http_wrapper->query()
303  );
304  $create_leaf_form->setId("select_course_explorer");
305 
306  $ref_expand = ROOT_FOLDER_ID;
307  if ($this->http_wrapper->query()->has("ref_repexpand")) {
308  $ref_expand = $this->http_wrapper->query()->retrieve("ref_repexpand", $this->refinery->kindlyTo()->int());
309  }
310 
311  $create_leaf_form->setExpand($ref_expand);
312  $create_leaf_form->setExpandTarget($this->ctrl->getLinkTarget($this, 'getContainerSelectionExplorer'));
313  $create_leaf_form->setAsynchExpanding(true);
314  $create_leaf_form->setTargetGet('target_id');
315  $create_leaf_form->setFrameTarget("_self");
316  $create_leaf_form->setClickable('crs', true);
317  $create_leaf_form->setTargetType('crs');
318  $create_leaf_form->setOutput(0);
319 
320  if ($convert_to_string) {
321  return $create_leaf_form->getOutput();
322  }
323 
324  return $create_leaf_form;
325  }
326 
331  {
332  $tmp_obj = new ilObjStudyProgrammeGUI();
333 
334  $create_node_form = $tmp_obj->getAsyncCreationForm();
335  $create_node_form->setTitle("");
336  $this->ctrl->setParameterByClass("ilobjstudyprogrammegui", "new_type", "prg");
337  $create_node_form->setFormAction($this->ctrl->getFormActionByClass("ilobjstudyprogrammegui", "save"));
338 
339  return $create_node_form;
340  }
341 
348  protected function create(): void
349  {
350  $parent_id = null;
351  if ($this->http_wrapper->query()->has("ref_id")) {
352  $parent_id = $this->http_wrapper->query()->retrieve("ref_id", $this->refinery->kindlyTo()->int());
353  }
354  $this->checkAccessOrFail('create', $parent_id);
355 
356  $parent = ilObjectFactoryWrapper::singleton()->getInstanceByRefId($parent_id);// TODO PHP8-REVIEW `$parent_id` is NULL, an `int` is expected
357  $accordion = new ilAccordionGUI();
358 
359  $added_slides = 0;
360  $content = "";
361  if ($parent instanceof ilObjStudyProgramme) {
362  // only allow adding new StudyProgramme-Node if there are no lp-children
363  if (!$parent->hasLPChildren()) {
364  $content_new_node = $this->getCreationForm()->getHTML();
365  $accordion->addItem($this->lng->txt('prg_create_new_node'), $content_new_node);
366  $added_slides++;
367  }
368 
369  /* only allow adding new LP-Children if there are no other StudyProgrammes
370  * AND creating crs references is activated in administration
371  */
372  if (!$parent->hasChildren() && $this->ilSetting->get("obj_dis_creation_crsr") === "") {
373  $content_new_leaf = ilUtil::getSystemMessageHTML(
374  $this->lng->txt('prg_please_select_a_course_for_creating_a_leaf')
375  );
376  $content_new_leaf .= $this->getContainerSelectionExplorer();
377 
378  $accordion->addItem($this->lng->txt('prg_create_new_leaf'), $content_new_leaf);
379  $added_slides++;
380  }
381 
382  if ($added_slides === 1) {
383  $accordion->setBehaviour(ilAccordionGUI::FIRST_OPEN);
384  }
385 
386  $content = $accordion->getHTML(true);
387  }
388 
389  // creating modal window output
390  $this->async_output_handler->setHeading($this->lng->txt("prg_async_" . $this->ctrl->getCmd()));
391  $this->async_output_handler->setContent($content);
392  $this->async_output_handler->terminate();
393  }
394 
400  protected function delete(): void
401  {
402  $this->checkAccessOrFail("delete");
403 
404  if (!$this->http_wrapper->query()->has("ref_id") || !$this->http_wrapper->query()->has("item_ref_id")) {
405  throw new ilException("Nothing to delete!");
406  }
407 
408  $element_ref_id = $this->http_wrapper->query()->retrieve("ref_id", $this->refinery->kindlyTo()->int());
409 
410  $cgui = new ilConfirmationGUI();
411 
412  $msg = $this->lng->txt("info_delete_sure");
413  if (!$this->ilSetting->get('enable_trash')) {
414  $msg .= "<br/>" . $this->lng->txt("info_delete_warning_no_trash");
415  }
416  $cgui->setHeaderText($msg);
417  $cgui->setFormAction($this->ctrl->getFormAction($this, 'confirmedDelete', '', true));
418  $cgui->setCancel($this->lng->txt("cancel"), "cancelDelete");
419  $cgui->setConfirm($this->lng->txt("confirm"), "confirmedDelete");
420  $cgui->setFormName('async_form');
421 
422  $obj_id = ilObject::_lookupObjectId((int) $element_ref_id);
423  $type = ilObject::_lookupType($obj_id);
424  $title = call_user_func(array(ilObjectFactory::getClassByType($type),'_lookupTitle'), $obj_id);
425  $alt = $this->lng->txt("icon") . " " . $this->lng->txt("obj_" . $type);
426 
427  $cgui->addItem(
428  "id[]",
429  (string)$element_ref_id,
430  $title,
431  ilObject::_getIcon($obj_id, "small", $type),
432  $alt
433  );
434  $cgui->addHiddenItem(
435  'item_ref_id',
436  $this->http_wrapper->query()->retrieve("item_ref_id", $this->refinery->kindlyTo()->string())
437  );
438 
439  $content = $cgui->getHTML();
440 
441  // creating the modal window output
442  $this->async_output_handler->setHeading($msg);
443  $this->async_output_handler->setContent($content);
444  $this->async_output_handler->terminate();
445  }
446 
452  protected function confirmedDelete(): string
453  {
454  $this->checkAccessOrFail("delete");
455 
456  if (
457  (!$this->http_wrapper->post()->has("id") || !$this->http_wrapper->post()->has("item_ref_id")) &&
458  is_array($this->http_wrapper->post()->retrieve(
459  "id[]",
460  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
461  ))
462  ) {
463  throw new ilException("No item select for deletion!");
464  }
465 
466  $ids = $this->http_wrapper->post()->retrieve(
467  "id",
468  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
469  );
470  $current_node = $this->http_wrapper->post()->retrieve("item_ref_id", $this->refinery->kindlyTo()->int());
471  $result = true;
472  $msg = '';
473 
474  foreach ($ids as $id) {
475  $obj = ilObjectFactoryWrapper::singleton()->getInstanceByRefId($id);
476 
477  $not_parent_of_current = true;
478  $not_root = true;
479 
480  // do some additional validation if it is a StudyProgramme
481  if ($obj instanceof ilObjStudyProgramme) {
482 
483  //check if you are not deleting a parent element of the current element
484  $children_of_node = ilObjStudyProgramme::getAllChildren($obj->getRefId());
485  $get_ref_ids = static function (ilObjStudyProgramme $obj): int {
486  return $obj->getRefId();
487  };
488 
489  $children_ref_ids = array_map($get_ref_ids, $children_of_node);
490  $not_parent_of_current = (!in_array($current_node, $children_ref_ids));
491 
492  $not_root = ($obj->getRoot() != null);// TODO PHP8-REVIEW This is always true
493  }
494 
495  if (
496  $current_node != $id &&
497  $not_root &&
498  $not_parent_of_current &&
499  $this->checkAccess('delete', $obj->getRefId())
500  ) {
501  ilRepUtil::deleteObjects(0, [$id]);
502 
503  // deletes the tree-open-node-session storage
504  if (isset($children_of_node)) {
505  $this->tree->closeCertainNode($id);
506  foreach ($children_of_node as $child) {
507  $this->tree->closeCertainNode($child->getRefId());
508  }
509  }
510 
511  $msg = $this->lng->txt("prg_deleted_safely");
512  } else {
513  $msg = $this->lng->txt("prg_not_allowed_node_to_delete");
514  $result = false;
515  }
516  }
517 
518  return ilAsyncOutputHandler::encodeAsyncResponse(array('success' => $result, 'message' => $msg));
519  }
520 
525  protected function cancelDelete(): string
526  {
528  }
529 
534  protected function initAsyncUIElements(): string
535  {
536  // add js files
540 
541  // add bootstrap modal
542  $settings_modal = ilModalGUI::getInstance();
543  $settings_modal->setId($this->modal_id);
544  $settings_modal->setType(ilModalGUI::TYPE_LARGE);
545  $this->tpl->addOnLoadCode('$("#' . $this->modal_id . '").study_programme_modal();');
546 
547  $content = $settings_modal->getHTML();
548 
549  // init js notifications
550  $notifications = new ilAsyncNotifications();
551  $notifications->addJsConfig('events', array('success' => array('study_programme-show_success')));
552  $notifications->initJs();
553 
554  // init tree selection explorer
555  $async_explorer = new ilAsyncContainerSelectionExplorer(
556  rawurldecode($this->ctrl->getLinkTarget($this, 'createNewLeaf', '', true)),
557  $this->refinery,
558  $this->http_wrapper->query()
559  );
560  $async_explorer->initJs();
561 
562  return $content;
563  }
564 
568  protected function getToolbar(): void
569  {
570  $save_order_btn = ilLinkButton::getInstance();
571  $save_order_btn->setId('save_order_button');
572  $save_order_btn->setUrl("javascript:void(0);");
573  $save_order_btn->setOnClick("$('body').trigger('study_programme-save_order');");
574  $save_order_btn->setCaption('prg_save_tree_order');
575 
576  $cancel_order_btn = ilLinkButton::getInstance();
577  $cancel_order_btn->setId('cancel_order_button');
578  $cancel_order_btn->setUrl("javascript:void(0);");
579  $cancel_order_btn->setOnClick("$('body').trigger('study_programme-cancel_order');");
580  $cancel_order_btn->setCaption('prg_cancel_tree_order');
581 
582  $this->toolbar->addButtonInstance($save_order_btn);
583  $this->toolbar->addButtonInstance($cancel_order_btn);
584  }
585 
589  protected function checkAccess(string $permission, int $ref_id = null): bool
590  {
591  if (is_null($ref_id)) {
592  $ref_id = $this->ref_id;
593  }
594  return $this->access->checkAccess($permission, '', $ref_id);
595  }
596 
602  protected function checkAccessOrFail(string $permission, int $ref_id = null): void
603  {
604  if (!$this->checkAccess($permission, $ref_id)) {
605  throw new ilException("You have no permission for " . $permission . " Object with ref_id " . $ref_id . "!");
606  }
607  }
608 }
static deleteObjects(int $a_cur_ref_id, array $a_ids, bool $throw_error_on_already_deleted=true)
Delete objects.
createNewLeaf()
Creates a new leaf Currently only course references can be created.
ILIAS HTTP Wrapper WrapperFactory $http_wrapper
Class ilAsyncOutputHandler Handles the output for async-requests.
exit
Definition: login.php:28
static getSystemMessageHTML(string $a_txt, string $a_type="info")
Get HTML for a system message.
Class ilObjStudyProgrammeGUI class ilObjStudyProgrammeGUI: ilPermissionGUI ilObjStudyProgrammeGUI: ...
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
confirmedDelete()
Deletes a node or a leaf in the tree.
checkAccessOrFail(string $permission, int $ref_id=null)
Checks permission of a object and throws an exception if they are not granted.
$type
const ROOT_FOLDER_ID
Definition: constants.php:32
static handleAsyncOutput(string $normal_content, string $async_content=null, bool $apply_to_tpl=true)
Handles async output.
Class ChatMainBarProvider .
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
checkAccess(string $permission, int $ref_id=null)
Checks permission of current tree or certain child of it.
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
getContainerSelectionExplorer(bool $convert_to_string=true)
Initialize the Course Explorer for creating a leaf.
__construct(ilGlobalTemplateInterface $tpl, ilCtrl $ilCtrl, ilAccess $ilAccess, ilToolbarGUI $ilToolbar, ilLanguage $lng, ilComponentLogger $ilLog, ILIAS $ilias, ilSetting $ilSetting, ilTree $ilTree, ilRbacAdmin $rbacadmin, ILIAS\HTTP\Wrapper\WrapperFactory $http_wrapper, ILIAS\Refinery\Factory $refinery)
$target_id
Definition: goto.php:52
string $modal_id
CSS-ID of the modal windows.
Component logger with individual log levels by component id.
loadLanguageModule(string $a_module)
Load language module.
initTree()
Initialize Tree Creates tree instance and set tree configuration.
static addJavaScript(bool $add_form_loader=false, string $js_base_path=null)
Adds all needed js By default is called by ilAsyncPropertyFormGUI::getHTML()
static addJavaScript(ilGlobalTemplate $main_tpl=null)
Add javascript files that are necessary to run accordion.
static encodeAsyncResponse(array $data=array())
Encode data as json for async output.
saveTreeOrder()
Saves tree node order Data is json encoded from the jstree component.
static _lookupObjectId(int $ref_id)
header include for all ilias files.
setId(string $a_val)
cancelDelete()
Cancel deletion Return a json string for the async handling.
executeCommand()
Execute GUI-commands If there is a async request the response is sent as a json string.
static addJavascript()
Adds the javascript to template.
static getClassByType(string $obj_type)
getCreationForm()
Returns the async creation form for StudyProgrammes.
static getInstance()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getAllChildren(int $a_ref_id, bool $include_references=false)
Get a list of all ilObjStudyProgrammes in the subtree starting at $a_ref_id.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getInstance(int $a_obj_id)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
Class ilAsyncContainerSelectionExplorer A class for async ilContainerSelectionExplorer which triggers...
Class ilAsyncPropertyFormGUI.
Class ilRbacAdmin Core functions for role based access control.
static _lookupType(int $id, bool $reference=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
initAsyncUIElements()
Initializes all elements used for async-interaction Adds HTML-skeleton for the bootstrap modal dialog...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
create()
Generates the modal window content for the creation form of nodes or leafs If there are already Study...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilObjStudyProgrammeTreeExplorerGUI $tree