1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5include_once("./Services/Skill/classes/class.ilPersonalSkill.php");
6include_once("./Services/Skill/classes/class.ilSkillProfile.php");
7
8/**
9 * Personal skills GUI class
10 *
11 * @author Alex Killing <alex.killing@gmx.de>
12 * @version $Id$
13 *
14 * @ilCtrl_Calls ilPersonalSkillsGUI:
15 *
16 * @ingroup ServicesSkill
17 */
18class ilPersonalSkillsGUI
19{
20    const LIST_SELECTED = "";
21    const LIST_PROFILES = "profiles";
22
23    protected $offline_mode;
24    protected $skill_tree;
25    public static $skill_tt_cnt = 1;
26    protected $actual_levels = array();
27    protected $gap_self_eval_levels = array();
28    protected $mode = "";
29    protected $history_view = false;
30    protected $trigger_objects_filter = array();
31    protected $intro_text = "";
32    protected $hidden_skills = array();
33
34    /**
35     * @var \ILIAS\DI\UIServices
36     */
37    protected $ui;
38
39    /**
40     * @var ilCtrl
41     */
42    protected $ctrl;
43
44    /**
45     * @var ilLanguage
46     */
47    protected $lng;
48
49    /**
50     * @var mixed
51     */
52    protected $help;
53
54    /**
55     * @var mixed
56     */
57    protected $setting;
58
59    /**
60     * @var ilObjUser
61     */
62    protected $user;
63
64    /**
65     * @var mixed
66     */
67    protected $tpl;
68
69    /**
70     * @var ilLanguage
71     */
72    protected $tabs;
73
74    /**
75     * @var ilToolbarGUI
76     */
77    protected $toolbar;
78
79    /**
80     * @var ilAccessHandler
81     */
82    protected $access;
83
84    /**
85     * @var \ILIAS\UI\Factory
86     */
87    protected $ui_fac;
88
89    /**
90     * @var \ILIAS\UI\Renderer
91     */
92    protected $ui_ren;
93    protected $obj_id = 0;
94    protected $obj_skills = array();
95
96    /**
97     * @var ilPersonalSkillsFilterGUI
98     */
99    protected $filter;
100
101    /**
102     * @var string
103     */
104    protected $list_mode = self::LIST_SELECTED;
105
106    /**
107     * Contructor
108     *
109     * @access public
110     */
111    public function __construct()
112    {
113        global $DIC;
114
115        $this->ctrl = $DIC->ctrl();
116        $this->lng = $DIC->language();
117        $this->help = $DIC["ilHelp"];
118        $this->setting = $DIC["ilSetting"];
119        $this->user = $DIC->user();
120        $this->tpl = $DIC["tpl"];
121        $this->tabs = $DIC->tabs();
122        $this->toolbar = $DIC->toolbar();
123        $this->access = $DIC->access();
124        $this->ui_fac = $DIC->ui()->factory();
125        $this->ui_ren = $DIC->ui()->renderer();
126        $this->ui = $DIC->ui();
127
128        $ilCtrl = $this->ctrl;
129        $ilHelp = $this->help;
130        $lng = $this->lng;
131        $ilSetting = $this->setting;
132
133
134        $lng->loadLanguageModule('skmg');
135        $ilHelp->setScreenIdComponent("skill");
136
137        $ilCtrl->saveParameter($this, "skill_id");
138        $ilCtrl->saveParameter($this, "tref_id");
139        $ilCtrl->saveParameter($this, "profile_id");
140        $ilCtrl->saveParameter($this, "list_mode");
141
142        $this->list_mode = $_GET["list_mode"];
143
144        $this->user_profiles = ilSkillProfile::getProfilesOfUser($this->user->getId());
145
146        include_once("./Services/Skill/classes/class.ilSkillTree.php");
147        $this->skill_tree = new ilSkillTree();
148
149        $this->use_materials = !$ilSetting->get("disable_personal_workspace");
150
151        include_once("./Services/Skill/classes/class.ilSkillManagementSettings.php");
152        $this->skmg_settings = new ilSkillManagementSettings();
153
154        $this->filter = new ilPersonalSkillsFilterGUI();
155    }
156
157    /**
158     * Get filter
159     *
160     * @return ilPersonalSkillsFilterGUI
161     */
162    protected function getFilter()
163    {
164        return $this->filter;
165    }
166
167
168    /**
169     * Set profile id
170     *
171     * @param  $a_val
172     */
173    public function setProfileId($a_val)
174    {
175        $this->profile_id = $a_val;
176    }
177
178    /**
179     * Get profile id
180     *
181     * @return
182     */
183    public function getProfileId()
184    {
185        return $this->profile_id;
186    }
187
188    /**
189     * Set self evaluation levels for gap analysis
190     *
191     * @param array $a_val self evaluation values key1: base_skill_id, key2: tref_id: value: level id
192     */
193    public function setGapAnalysisSelfEvalLevels(array $a_val)
194    {
195        $this->gap_self_eval_levels = $a_val;
196    }
197
198    /**
199     * Get self evaluation levels for gap analysis
200     *
201     * @return array self evaluation values key1: base_skill_id, key2: tref_id: value: level id
202     */
203    public function getGapAnalysisSelfEvalLevels()
204    {
205        return $this->gap_self_eval_levels;
206    }
207
208    /**
209     * Set history view
210     *
211     * @param bool $a_val history view
212     */
213    public function setHistoryView($a_val)
214    {
215        $this->history_view = $a_val;
216    }
217
218    /**
219     * Get history view
220     *
221     * @return bool history view
222     */
223    public function getHistoryView()
224    {
225        return $this->history_view;
226    }
227
228    /**
229     * @return array
230     */
231    public function getTriggerObjectsFilter()
232    {
233        return $this->trigger_objects_filter;
234    }
235
236    /**
237     * @param array $trigger_objects_filter
238     */
239    public function setTriggerObjectsFilter($trigger_objects_filter)
240    {
241        $this->trigger_objects_filter = $trigger_objects_filter;
242    }
243
244    /**
245     * Set intro text
246     *
247     * @param string $a_val intro text html
248     */
249    public function setIntroText($a_val)
250    {
251        $this->intro_text = $a_val;
252    }
253
254    /**
255     * Get intro text
256     *
257     * @return string intro text html
258     */
259    public function getIntroText()
260    {
261        return $this->intro_text;
262    }
263
264    /**
265     * Hide skill
266     *
267     * @param
268     * @return
269     */
270    public function hideSkill($a_skill_id, $a_tref_id = 0)
271    {
272        $this->hidden_skills[] = $a_skill_id . ":" . $a_tref_id;
273    }
274
275    /**
276     * Determine current profile id
277     *
278     * @param
279     * @return
280     */
281    public function determineCurrentProfile()
282    {
283        $ilCtrl = $this->ctrl;
284
285        if (count($this->user_profiles) == 0) {
286            return;
287        }
288        $current_prof_id = 0;
289        if ((int) $_GET["profile_id"] > 0) {
290            foreach ($this->user_profiles as $p) {
291                if ($p["id"] == (int) $_GET["profile_id"]) {
292                    $current_prof_id = (int) $_GET["profile_id"];
293                }
294            }
295        }
296
297        if ($current_prof_id == 0 && !(is_array($this->obj_skills) && $this->obj_id > 0)) {
298            $current_prof_id = $this->user_profiles[0]["id"];
299        }
300        $ilCtrl->setParameter($this, "profile_id", $current_prof_id);
301        $this->setProfileId($current_prof_id);
302    }
303
304    /**
305     * Set object skills
306     *
307     * @param int $a_obj_id object id
308     * @param array $a_skills skills array
309     */
310    public function setObjectSkills($a_obj_id, $a_skills = null)
311    {
312        $this->obj_id = $a_obj_id;
313        $this->obj_skills = $a_skills;
314    }
315
316    /**
317     * Execute command
318     *
319     * @access public
320     *
321     */
322    public function executeCommand()
323    {
324        $ilCtrl = $this->ctrl;
325        $ilUser = $this->user;
326        $lng = $this->lng;
327        $tpl = $this->tpl;
328
329        $next_class = $ilCtrl->getNextClass($this);
330
331
332        // determin standard command
333        $std_cmd = "listSkills";
334
335        $cmd = $ilCtrl->getCmd($std_cmd);
336
337        //$tpl->setTitle($lng->txt("skills"));
338        //$tpl->setTitleIcon(ilUtil::getImagePath("icon_skmg.svg"));
339
340        switch ($next_class) {
341            default:
342                $this->$cmd();
343                break;
344        }
345        return true;
346    }
347
348    /**
349     * Set tabs
350     */
351    public function setTabs($a_activate)
352    {
353        $ilCtrl = $this->ctrl;
354        $lng = $this->lng;
355        $ilTabs = $this->tabs;
356
357        // list skills
358        $ilCtrl->setParameter($this, "list_mode", self::LIST_SELECTED);
359        $ilTabs->addSubTab(
360            "list_skills",
361            $lng->txt("skmg_selected_skills"),
362            $ilCtrl->getLinkTarget($this, "render")
363        );
364
365        if (count($this->user_profiles) > 0) {
366            $ilCtrl->setParameter($this, "list_mode", self::LIST_PROFILES);
367            $ilTabs->addSubTab(
368                "profile",
369                $lng->txt("skmg_assigned_profiles"),
370                $ilCtrl->getLinkTarget($this, "render")
371            );
372        }
373
374        $ilCtrl->clearParameterByClass(get_class($this), "list_mode");
375
376        // assign materials
377
378        $ilTabs->activateSubTab($a_activate);
379    }
380
381    public function setOfflineMode($a_file_path)
382    {
383        $this->offline_mode = $a_file_path;
384    }
385
386    /**
387     * Render
388     */
389    protected function render()
390    {
391        switch ($this->list_mode) {
392            case self::LIST_PROFILES:
393                $this->listAssignedProfile();
394                break;
395
396            default:
397                $this->listSkills();
398                break;
399        }
400    }
401
402
403    /**
404     * List skills
405     */
406    public function listSkills()
407    {
408        $ilCtrl = $this->ctrl;
409        $ilUser = $this->user;
410        $lng = $this->lng;
411        $main_tpl = $this->tpl;
412        $ilToolbar = $this->toolbar;
413
414        $tpl = new ilTemplate("tpl.skill_filter.html", true, true, "Services/Skill");
415
416        $this->setTabs("list_skills");
417
418        include_once("./Services/Skill/classes/class.ilSkillTree.php");
419        $stree = new ilSkillTree();
420
421        // skill selection / add new personal skill
422        $ilToolbar->addFormButton(
423            $lng->txt("skmg_add_skill"),
424            "listSkillsForAdd"
425        );
426        $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
427
428        $filter_toolbar = new ilToolbarGUI();
429        $filter_toolbar->setFormAction($ilCtrl->getFormAction($this));
430        $this->getFilter()->addToToolbar($filter_toolbar, false);
431
432        $skills = ilPersonalSkill::getSelectedUserSkills($ilUser->getId());
433        $html = "";
434        foreach ($skills as $s) {
435            $path = $stree->getSkillTreePath($s["skill_node_id"]);
436
437            // check draft
438            foreach ($path as $p) {
439                if ($p["status"] == ilSkillTreeNode::STATUS_DRAFT) {
440                    continue(2);
441                }
442            }
443            $html .= $this->getSkillHTML($s["skill_node_id"], 0, true);
444        }
445
446        // list skills
447        //		include_once("./Services/Skill/classes/class.ilPersonalSkillTableGUI.php");
448        //		$sktab = new ilPersonalSkillTableGUI($this, "listSkills");
449
450        if ($html != "") {
451            $filter_toolbar->addFormButton($this->lng->txt("skmg_refresh_view"), "applyFilter");
452            $tpl->setVariable("FILTER", $filter_toolbar->getHTML());
453            $html = $tpl->get() . $html;
454        }
455
456        $main_tpl->setContent($html);
457    }
458
459    /**
460     * Apply filter
461     */
462    protected function applyFilter()
463    {
464        $this->getFilter()->save();
465        $this->ctrl->redirect($this, "listSkills");
466    }
467
468    /**
469     * Apply filter for profiles view
470     */
471    protected function applyFilterAssignedProfiles()
472    {
473        $this->getFilter()->save();
474        $this->ctrl->redirect($this, "listAssignedProfile");
475    }
476
477
478    /**
479     * Get skill presentation HTML
480     *
481     * $a_top_skill_id is a node of the skill "main tree", it can be a tref id!
482     * - called in listSkills (this class) -> $a_top_skill is the selected user skill (main tree node id), tref_id not set
483     * - called in ilPortfolioPage -> $a_top_skill is the selected user skill (main tree node id), tref_id not set
484     * - called in getGapAnalysis (this class) -> $a_top_skill id is the (basic) skill_id, tref_id may be set
485     */
486    public function getSkillHTML($a_top_skill_id, $a_user_id = 0, $a_edit = false, $a_tref_id = 0)
487    {
488        // user interface plugin slot + default rendering
489        include_once("./Services/UIComponent/classes/class.ilUIHookProcessor.php");
490        $uip = new ilUIHookProcessor(
491            "Services/Skill",
492            "personal_skill_html",
493            array("personal_skills_gui" => $this, "top_skill_id" => $a_top_skill_id, "user_id" => $a_user_id,
494                "edit" => $a_edit, "tref_id" => $a_tref_id)
495        );
496        if (!$uip->replaced()) {
497            $skill_html = $this->renderSkillHTML($a_top_skill_id, $a_user_id, $a_edit, $a_tref_id);
498        }
499        $skill_html = $uip->getHTML($skill_html);
500
501        return $skill_html;
502    }
503
504    /**
505     * Render skill html
506     *
507     * @param
508     * @return
509     */
510    public function renderSkillHTML($a_top_skill_id, $a_user_id = 0, $a_edit = false, $a_tref_id = 0)
511    {
512        $ilCtrl = $this->ctrl;
513        $ilUser = $this->user;
514        $lng = $this->lng;
515
516        $sub_panels = array();
517
518        if ($a_user_id == 0) {
519            $user = $ilUser;
520        } else {
521            $user = new ilObjUser($a_user_id);
522        }
523
524        $tpl = new ilTemplate("tpl.skill_pres.html", true, true, "Services/Skill");
525
526        include_once("./Services/Skill/classes/class.ilSkillTree.php");
527        $stree = new ilSkillTree();
528
529        include_once("./Services/Skill/classes/class.ilVirtualSkillTree.php");
530        $vtree = new ilVirtualSkillTree();
531        $tref_id = $a_tref_id;
532        $skill_id = $a_top_skill_id;
533        if (ilSkillTreeNode::_lookupType($a_top_skill_id) == "sktr") {
534            include_once("./Services/Skill/classes/class.ilSkillTemplateReference.php");
535            $tref_id = $a_top_skill_id;
536            $skill_id = ilSkillTemplateReference::_lookupTemplateId($a_top_skill_id);
537        }
538        $b_skills = $vtree->getSubTreeForCSkillId($skill_id . ":" . $tref_id, true);
539
540        foreach ($b_skills as $bs) {
541            $bs["id"] = $bs["skill_id"];
542            $bs["tref"] = $bs["tref_id"];
543
544            $path = $stree->getSkillTreePath($bs["id"], $bs["tref"]);
545
546            $panel_comps = array();
547
548
549            // check draft
550            foreach ($path as $p) {
551                if ($p["status"] == ilSkillTreeNode::STATUS_DRAFT) {
552                    continue(2);
553                }
554            }
555            reset($path);
556
557            $skill = ilSkillTreeNodeFactory::getInstance($bs["id"]);
558            $level_data = $skill->getLevelData();
559
560
561            // skill description
562            $panel_comps[] = $this->ui_fac->legacy($this->getSkillDescription($skill));
563
564
565            if ($this->getProfileId() > 0) {
566                if (!$this->skmg_settings->getHideProfileBeforeSelfEval() ||
567                    ilBasicSkill::hasSelfEvaluated($user->getId(), $bs["id"], $bs["tref"])) {
568                    if ($this->getFilter()->showTargetLevel()) {
569                        $panel_comps[] = $this->ui_fac->legacy($this->getProfileTargetItem($this->getProfileId(), $level_data, $bs["tref"]));
570                    }
571                }
572            }
573
574            if ($this->mode == "gap" && !$this->history_view) {
575                $panel_comps[] = $this->ui_fac->legacy($this->getActualGapItem($level_data, $bs["tref"]) . "");
576                $panel_comps[] = $this->ui_fac->legacy($this->getSelfEvalGapItem($level_data, $bs["tref"]) . "");
577            } else {
578                // get date of self evaluation
579                $se_date = ilPersonalSkill::getSelfEvaluationDate($user->getId(), $a_top_skill_id, $bs["tref"], $bs["id"]);
580                $se_rendered = ($se_date == "")
581                    ? true
582                    : false;
583
584                // get all object triggered entries and render them
585                foreach ($skill->getAllHistoricLevelEntriesOfUser($bs["tref"], $user->getId(), ilBasicSkill::EVAL_BY_ALL) as $level_entry) {
586                    if (count($this->getTriggerObjectsFilter()) && !in_array($level_entry['trigger_obj_id'], $this->getTriggerObjectsFilter())) {
587                        continue;
588                    }
589
590                    // render the self evaluation at the correct position within the list of object triggered entries
591                    if ($se_date > $level_entry["status_date"] && !$se_rendered) {
592                        $se_rendered = true;
593                    }
594                    if ($this->getFilter()->isInRange($level_data, $level_entry)) {
595                        $panel_comps[] = $this->ui_fac->legacy($this->getEvalItem($level_data, $level_entry));
596                    }
597                }
598            }
599
600            // materials (new)
601            if ($this->mode != "gap") {
602                if ($this->getFilter()->showMaterialsRessources() && $this->use_materials) {
603                    $mat = $this->getMaterials($level_data, $bs["tref"], $user->getId());
604                }
605                if ($mat != "") {
606                    $panel_comps[] = $this->ui_fac->legacy($mat);
607                }
608            }
609
610            // suggested resources
611            if ($this->getFilter()->showMaterialsRessources()) {
612                $sugg = $this->getSuggestedResources($this->getProfileId(), $level_data, $bs["id"], $bs["tref"]);
613            }
614            if ($sugg != "") {
615                $panel_comps[] = $this->ui_fac->legacy($sugg);
616            }
617
618            $title = $sep = "";
619            $found = false;
620            foreach ($path as $p) {
621                if ($found) {
622                    $title .= $sep . $p["title"];
623                    $sep = " > ";
624                }
625                if ($a_top_skill_id == $p["child"]) {
626                    $found = true;
627                }
628            }
629
630            $sub = $this->ui_fac->panel()->sub((string) $title, $panel_comps);
631            if ($a_edit) {
632                $actions = array();
633                $ilCtrl->setParameterByClass("ilpersonalskillsgui", "skill_id", $a_top_skill_id);
634                $ilCtrl->setParameterByClass("ilpersonalskillsgui", "tref_id", $bs["tref"]);
635                $ilCtrl->setParameterByClass("ilpersonalskillsgui", "basic_skill_id", $bs["id"]);
636                if ($this->use_materials) {
637                    $actions[] = $this->ui_fac->button()->shy(
638                        $lng->txt('skmg_assign_materials'),
639                        $ilCtrl->getLinkTargetByClass("ilpersonalskillsgui", "assignMaterials")
640                    );
641                }
642                $actions[] = $this->ui_fac->button()->shy(
643                    $lng->txt('skmg_self_evaluation'),
644                    $ilCtrl->getLinkTargetByClass("ilpersonalskillsgui", "selfEvaluation")
645                );
646                $sub = $sub->withActions($this->ui_fac->dropdown()->standard($actions)->withLabel($lng->txt("actions")));
647            }
648
649            $sub_panels[] = $sub;
650
651            $tpl->parseCurrentBlock();
652        }
653
654        $panel = $this->ui_fac->panel()->standard(
655            (string) ilSkillTreeNode::_lookupTitle($skill_id, $tref_id),
656            $sub_panels
657        );
658
659        if ($a_edit && $this->getProfileId() == 0) {
660            $actions = array();
661
662            $ilCtrl->setParameterByClass("ilpersonalskillsgui", "skill_id", $a_top_skill_id);
663            $actions[] = $this->ui_fac->button()->shy(
664                $lng->txt('skmg_remove_skill'),
665                $ilCtrl->getLinkTargetByClass("ilpersonalskillsgui", "confirmSkillRemove")
666            );
667
668            $panel = $panel->withActions($this->ui_fac->dropdown()->standard($actions)->withLabel($lng->txt("actions")));
669        }
670
671        return $this->ui_ren->render($panel);
672    }
673
674
675    /**
676     * Get material file name and goto url
677     *
678     * @param int $a_wsp_id
679     * @return array caption, url
680     */
681    public function getMaterialInfo($a_wsp_id, $a_user_id)
682    {
683        if (!$this->ws_tree) {
684            include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
685            include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php";
686            $this->ws_tree = new ilWorkspaceTree($a_user_id);
687            $this->ws_access = new ilWorkspaceAccessHandler($caption);
688        }
689
690        $obj_id = $this->ws_tree->lookupObjectId($a_wsp_id);
691        $caption = ilObject::_lookupTitle($obj_id);
692
693        if (!$this->offline_mode) {
694            $url = $this->ws_access->getGotoLink($a_wsp_id, $obj_id);
695        } else {
696            $url = $this->offline_mode . "file_" . $obj_id . "/";
697
698            // all possible material types for now
699            switch (ilObject::_lookupType($obj_id)) {
700                case "tstv":
701                    include_once "Modules/Test/classes/class.ilObjTestVerification.php";
702                    $obj = new ilObjTestVerification($obj_id, false);
703                    $url .= $obj->getOfflineFilename();
704                    break;
705
706                case "excv":
707                    include_once "Modules/Exercise/classes/class.ilObjExerciseVerification.php";
708                    $obj = new ilObjExerciseVerification($obj_id, false);
709                    $url .= $obj->getOfflineFilename();
710                    break;
711
712                case "crsv":
713                    include_once "Modules/Course/classes/Verification/class.ilObjCourseVerification.php";
714                    $obj = new ilObjCourseVerification($obj_id, false);
715                    $url .= $obj->getOfflineFilename();
716                    break;
717
718                case "scov":
719                    include_once "Modules/ScormAicc/classes/Verification/class.ilObjSCORMVerification.php";
720                    $obj = new ilObjSCORMVerification($obj_id, false);
721                    $url .= $obj->getOfflineFilename();
722                    break;
723
724                case "file":
725                    $file = new ilObjFile($obj_id, false);
726                    $url .= $file->getFilename();
727                    break;
728            }
729        }
730
731        return array($caption, $url);
732    }
733
734    /**
735     * Add personal skill
736     */
737    public function addSkill()
738    {
739        $ilCtrl = $this->ctrl;
740        $ilUser = $this->user;
741        $lng = $this->lng;
742
743        ilPersonalSkill::addPersonalSkill($ilUser->getId(), (int) $_GET["obj_id"]);
744
745        ilUtil::sendSuccess($lng->txt("msg_object_modified"));
746        $ilCtrl->redirect($this, "listSkills");
747    }
748
749
750
751    /**
752     * Confirm skill remove
753     */
754    public function confirmSkillRemove()
755    {
756        $lng = $this->lng;
757        $tpl = $this->tpl;
758        $ilCtrl = $this->ctrl;
759
760        include_once("./Services/Skill/classes/class.ilSkillTreeNode.php");
761        if ($_GET["skill_id"] > 0) {
762            $_POST["id"][] = $_GET["skill_id"];
763        }
764        if (!is_array($_POST["id"]) || count($_POST["id"]) == 0) {
765            ilUtil::sendInfo($lng->txt("no_checkbox"), true);
766            $ilCtrl->redirect($this, "listSkills");
767        } else {
768            include_once("./Services/Utilities/classes/class.ilConfirmationGUI.php");
769            $cgui = new ilConfirmationGUI();
770            $cgui->setFormAction($ilCtrl->getFormAction($this));
771            $cgui->setHeaderText($lng->txt("skmg_really_remove_skills"));
772            $cgui->setCancel($lng->txt("cancel"), "listSkills");
773            $cgui->setConfirm($lng->txt("remove"), "removeSkills");
774
775            foreach ($_POST["id"] as $i) {
776                $cgui->addItem("id[]", $i, ilSkillTreeNode::_lookupTitle($i));
777            }
778
779            $tpl->setContent($cgui->getHTML());
780        }
781    }
782
783    /**
784     * Remove skills
785     */
786    public function removeSkills()
787    {
788        $ilCtrl = $this->ctrl;
789        $ilUser = $this->user;
790        $lng = $this->lng;
791
792        if (is_array($_POST["id"])) {
793            foreach ($_POST["id"] as $n_id) {
794                ilPersonalSkill::removeSkill($ilUser->getId(), $n_id);
795            }
796        }
797
798        ilUtil::sendSuccess($lng->txt("msg_object_modified"));
799        $ilCtrl->redirect($this, "listSkills");
800    }
801
802
803    //
804    // Materials assignments
805    //
806
807    /**
808     * Assign materials to skill levels
809     *
810     * @param
811     * @return
812     */
813    public function assignMaterials()
814    {
815        $ilCtrl = $this->ctrl;
816        $lng = $this->lng;
817        $tpl = $this->tpl;
818        $ilToolbar = $this->toolbar;
819        $ilTabs = $this->tabs;
820
821
822        $ilTabs->setBackTarget(
823            $lng->txt("back"),
824            $ilCtrl->getLinkTarget($this, "render")
825        );
826
827        $ilCtrl->saveParameter($this, "skill_id");
828        $ilCtrl->saveParameter($this, "basic_skill_id");
829        $ilCtrl->saveParameter($this, "tref_id");
830
831        include_once("./Services/Skill/classes/class.ilSkillTreeNode.php");
832        $tpl->setTitle(ilSkillTreeNode::_lookupTitle((int) $_GET["skill_id"]));
833        $tpl->setTitleIcon(ilUtil::getImagePath("icon_" .
834            ilSkillTreeNode::_lookupType((int) $_GET["skill_id"]) .
835            ".svg"));
836
837        // basic skill selection
838        include_once("./Services/Skill/classes/class.ilVirtualSkillTree.php");
839        $vtree = new ilVirtualSkillTree();
840        $tref_id = 0;
841        $skill_id = (int) $_GET["skill_id"];
842        if (ilSkillTreeNode::_lookupType((int) $_GET["skill_id"]) == "sktr") {
843            include_once("./Services/Skill/classes/class.ilSkillTemplateReference.php");
844            $tref_id = $_GET["skill_id"];
845            $skill_id = ilSkillTemplateReference::_lookupTemplateId($_GET["skill_id"]);
846        }
847        $bs = $vtree->getSubTreeForCSkillId($skill_id . ":" . $tref_id, true);
848
849        $options = array();
850        foreach ($bs as $b) {
851            //$options[$b["id"]] = ilSkillTreeNode::_lookupTitle($b["id"]);
852            $options[$b["skill_id"]] = ilSkillTreeNode::_lookupTitle($b["skill_id"]);
853        }
854
855        $cur_basic_skill_id = ((int) $_POST["basic_skill_id"] > 0)
856            ? (int) $_POST["basic_skill_id"]
857            : (((int) $_GET["basic_skill_id"] > 0)
858                ? (int) $_GET["basic_skill_id"]
859                : key($options));
860
861        $ilCtrl->setParameter($this, "basic_skill_id", $cur_basic_skill_id);
862
863        include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
864        $si = new ilSelectInputGUI($lng->txt("skmg_skill"), "basic_skill_id");
865        $si->setOptions($options);
866        $si->setValue($cur_basic_skill_id);
867        $ilToolbar->addInputItem($si, true);
868        $ilToolbar->addFormButton(
869            $lng->txt("select"),
870            "assignMaterials"
871        );
872
873        $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
874
875        // table
876        include_once("./Services/Skill/classes/class.ilSkillAssignMaterialsTableGUI.php");
877        $tab = new ilSkillAssignMaterialsTableGUI(
878            $this,
879            "assignMaterials",
880            (int) $_GET["skill_id"],
881            (int) $_GET["tref_id"],
882            $cur_basic_skill_id
883        );
884
885        $tpl->setContent($tab->getHTML());
886    }
887
888
889    /**
890     * Assign materials to skill level
891     *
892     * @param
893     * @return
894     */
895    public function assignMaterial()
896    {
897        $ilCtrl = $this->ctrl;
898        $ilUser = $this->user;
899        $lng = $this->lng;
900        $tpl = $this->tpl;
901        $ilTabs = $this->tabs;
902        $ilSetting = $this->setting;
903        $ui = $this->ui;
904
905        if (!$ilSetting->get("disable_personal_workspace")) {
906            $url = 'ilias.php?baseClass=ilPersonalDesktopGUI&amp;cmd=jumpToWorkspace';
907            $mbox = $ui->factory()->messageBox()->info($lng->txt("skmg_ass_materials_from_workspace"))
908                ->withLinks([$ui->factory()->link()->standard(
909                    $lng->txt("personal_workspace"),
910                    $url
911                )]);
912            $message = $ui->renderer()->render($mbox);
913        }
914
915        $ilCtrl->saveParameter($this, "skill_id");
916        $ilCtrl->saveParameter($this, "level_id");
917        $ilCtrl->saveParameter($this, "tref_id");
918        $ilCtrl->saveParameter($this, "basic_skill_id");
919
920        $ilTabs->setBackTarget(
921            $lng->txt("back"),
922            $ilCtrl->getLinkTarget($this, "assignMaterials")
923        );
924
925
926        include_once("./Services/PersonalWorkspace/classes/class.ilWorkspaceExplorerGUI.php");
927        $exp = new ilWorkspaceExplorerGUI($ilUser->getId(), $this, "assignMaterial", $this, "");
928        $exp->setTypeWhiteList(array("blog", "wsrt", "wfld", "file", "tstv", "excv"));
929        $exp->setSelectableTypes(array("file", "tstv", "excv"));
930        $exp->setSelectMode("wsp_id", true);
931        if ($exp->handleCommand()) {
932            return;
933        }
934
935        // fill template
936        $mtpl = new ilTemplate("tpl.materials_selection.html", true, true, "Services/Skill");
937        $mtpl->setVariable("EXP", $exp->getHTML());
938
939        // toolbars
940        $tb = new ilToolbarGUI();
941        $tb->addFormButton(
942            $lng->txt("select"),
943            "selectMaterial"
944        );
945        $tb->setFormAction($ilCtrl->getFormAction($this));
946        $tb->setOpenFormTag(true);
947        $tb->setCloseFormTag(false);
948        $mtpl->setVariable("TOOLBAR1", $tb->getHTML());
949        $tb->setOpenFormTag(false);
950        $tb->setCloseFormTag(true);
951        $mtpl->setVariable("TOOLBAR2", $tb->getHTML());
952
953        $tpl->setContent($message . $mtpl->get());
954    }
955
956    /**
957     * Select material
958     */
959    public function selectMaterial()
960    {
961        $ilCtrl = $this->ctrl;
962        $ilUser = $this->user;
963        $lng = $this->lng;
964
965
966        include_once("./Services/Skill/classes/class.ilPersonalSkill.php");
967        if (is_array($_POST["wsp_id"])) {
968            foreach ($_POST["wsp_id"] as $w) {
969                ilPersonalSkill::assignMaterial(
970                    $ilUser->getId(),
971                    (int) $_GET["skill_id"],
972                    (int) $_GET["tref_id"],
973                    (int) $_GET["basic_skill_id"],
974                    (int) $_GET["level_id"],
975                    (int) $w
976                );
977            }
978            ilUtil::sendSuccess($lng->txt("msg_obj_modified"), true);
979        }
980
981        $ilCtrl->saveParameter($this, "skill_id");
982        $ilCtrl->saveParameter($this, "level_id");
983        $ilCtrl->saveParameter($this, "tref_id");
984        $ilCtrl->saveParameter($this, "basic_skill_id");
985
986        $ilCtrl->redirect($this, "assignMaterials");
987    }
988
989
990    /**
991     * Remove material
992     */
993    public function removeMaterial()
994    {
995        $ilCtrl = $this->ctrl;
996        $ilUser = $this->user;
997        $lng = $this->lng;
998
999
1000        ilPersonalSkill::removeMaterial(
1001            $ilUser->getId(),
1002            (int) $_GET["tref_id"],
1003            (int) $_GET["level_id"],
1004            (int) $_GET["wsp_id"]
1005        );
1006        ilUtil::sendSuccess($lng->txt("msg_obj_modified"), true);
1007        $ilCtrl->redirect($this, "assignMaterials");
1008    }
1009
1010
1011    //
1012    // Self evaluation
1013    //
1014
1015    /**
1016     * Assign materials to skill levels
1017     *
1018     * @param
1019     * @return
1020     */
1021    public function selfEvaluation()
1022    {
1023        $ilCtrl = $this->ctrl;
1024        $lng = $this->lng;
1025        $tpl = $this->tpl;
1026        $ilToolbar = $this->toolbar;
1027        $ilTabs = $this->tabs;
1028
1029
1030        $ilTabs->setBackTarget(
1031            $lng->txt("back"),
1032            $ilCtrl->getLinkTarget($this, "render")
1033        );
1034
1035        $ilCtrl->saveParameter($this, "skill_id");
1036        $ilCtrl->saveParameter($this, "basic_skill_id");
1037        $ilCtrl->saveParameter($this, "tref_id");
1038
1039        include_once("./Services/Skill/classes/class.ilSkillTreeNode.php");
1040        $tpl->setTitle(ilSkillTreeNode::_lookupTitle((int) $_GET["skill_id"]));
1041        $tpl->setTitleIcon(ilUtil::getImagePath("icon_" .
1042            ilSkillTreeNode::_lookupType((int) $_GET["skill_id"]) .
1043            ".svg"));
1044
1045        // basic skill selection
1046        include_once("./Services/Skill/classes/class.ilVirtualSkillTree.php");
1047        $vtree = new ilVirtualSkillTree();
1048        $tref_id = 0;
1049        $skill_id = (int) $_GET["skill_id"];
1050        if (ilSkillTreeNode::_lookupType((int) $_GET["skill_id"]) == "sktr") {
1051            include_once("./Services/Skill/classes/class.ilSkillTemplateReference.php");
1052            $tref_id = $_GET["skill_id"];
1053            $skill_id = ilSkillTemplateReference::_lookupTemplateId($_GET["skill_id"]);
1054        }
1055        $bs = $vtree->getSubTreeForCSkillId($skill_id . ":" . $tref_id, true);
1056
1057
1058        $options = array();
1059        foreach ($bs as $b) {
1060            $options[$b["skill_id"]] = ilSkillTreeNode::_lookupTitle($b["skill_id"]);
1061        }
1062
1063        $cur_basic_skill_id = ((int) $_POST["basic_skill_id"] > 0)
1064            ? (int) $_POST["basic_skill_id"]
1065            : (((int) $_GET["basic_skill_id"] > 0)
1066                ? (int) $_GET["basic_skill_id"]
1067                : key($options));
1068
1069        $ilCtrl->setParameter($this, "basic_skill_id", $cur_basic_skill_id);
1070
1071        include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
1072        $si = new ilSelectInputGUI($lng->txt("skmg_skill"), "basic_skill_id");
1073        $si->setOptions($options);
1074        $si->setValue($cur_basic_skill_id);
1075        $ilToolbar->addInputItem($si, true);
1076        $ilToolbar->addFormButton(
1077            $lng->txt("select"),
1078            "selfEvaluation"
1079        );
1080
1081        $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
1082
1083        // table
1084        include_once("./Services/Skill/classes/class.ilSelfEvaluationSimpleTableGUI.php");
1085        $tab = new ilSelfEvaluationSimpleTableGUI(
1086            $this,
1087            "selfEvaluation",
1088            (int) $_GET["skill_id"],
1089            (int) $_GET["tref_id"],
1090            $cur_basic_skill_id
1091        );
1092
1093        $tpl->setContent($tab->getHTML());
1094    }
1095
1096    /**
1097     * Save self evaluation
1098     */
1099    public function saveSelfEvaluation()
1100    {
1101        $ilCtrl = $this->ctrl;
1102        $ilUser = $this->user;
1103        $lng = $this->lng;
1104
1105        ilPersonalSkill::saveSelfEvaluation(
1106            $ilUser->getId(),
1107            (int) $_GET["skill_id"],
1108            (int) $_GET["tref_id"],
1109            (int) $_GET["basic_skill_id"],
1110            (int) $_POST["se"]
1111        );
1112        ilUtil::sendSuccess($lng->txt("msg_obj_modified"), true);
1113
1114        /*		$ilCtrl->saveParameter($this, "skill_id");
1115                $ilCtrl->saveParameter($this, "level_id");
1116                $ilCtrl->saveParameter($this, "tref_id");
1117                $ilCtrl->saveParameter($this, "basic_skill_id");*/
1118
1119        $ilCtrl->redirect($this, "render");
1120    }
1121
1122    /**
1123     * LIst skills for adding
1124     *
1125     * @param
1126     * @return
1127     */
1128    public function listSkillsForAdd()
1129    {
1130        $ilCtrl = $this->ctrl;
1131        $lng = $this->lng;
1132        $tpl = $this->tpl;
1133        $ilTabs = $this->tabs;
1134
1135
1136        $ilTabs->setBackTarget(
1137            $lng->txt("back"),
1138            $ilCtrl->getLinkTarget($this, "")
1139        );
1140
1141        include_once("./Services/Skill/classes/class.ilPersonalSkillExplorerGUI.php");
1142        $exp = new ilPersonalSkillExplorerGUI($this, "listSkillsForAdd", $this, "addSkill");
1143        if ($exp->getHasSelectableNodes()) {
1144            if (!$exp->handleCommand()) {
1145                $tpl->setContent($exp->getHTML());
1146            }
1147            ilUtil::sendInfo($lng->txt("skmg_select_skill"));
1148        } else {
1149            ilUtil::sendInfo($lng->txt("skmg_no_nodes_selectable"));
1150        }
1151    }
1152
1153    /**
1154     * List profiles
1155     *
1156     * @param
1157     */
1158    public function listProfilesForGap()
1159    {
1160        $tpl = $this->tpl;
1161
1162        //$a_user_id = $ilUser->getId();
1163
1164        //$profiles = ilSkillProfile::getProfilesOfUser($a_user_id);
1165
1166        if (count($this->user_profiles) == 0 && $this->obj_skills == null) {
1167            return;
1168        }
1169
1170        $this->determineCurrentProfile();
1171        $this->showProfileSelectorToolbar();
1172
1173        $tpl->setContent($this->getGapAnalysisHTML());
1174    }
1175
1176
1177
1178    /**
1179     * Show profile selector toolbar
1180     */
1181    public function showProfileSelectorToolbar()
1182    {
1183        $ilToolbar = $this->toolbar;
1184        $lng = $this->lng;
1185        $ilCtrl = $this->ctrl;
1186
1187        $options = array();
1188        if (is_array($this->obj_skills) && $this->obj_id > 0) {
1189            $options[0] = $lng->txt("obj_" . ilObject::_lookupType($this->obj_id)) . ": " . ilObject::_lookupTitle($this->obj_id);
1190        }
1191
1192        foreach ($this->user_profiles as $p) {
1193            $options[$p["id"]] = $lng->txt("skmg_profile") . ": " . $p["title"];
1194        }
1195
1196        include_once("./Services/Form/classes/class.ilSelectInputGUI.php");
1197        $si = new ilSelectInputGUI($lng->txt("skmg_profile"), "profile_id");
1198        $si->setOptions($options);
1199        $si->setValue($this->getProfileId());
1200        $ilToolbar->addInputItem($si, true);
1201        $ilToolbar->addFormButton(
1202            $lng->txt("select"),
1203            "selectProfile"
1204        );
1205        $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
1206    }
1207
1208
1209    /**
1210     * Set gap analysis actual status mode "per type"
1211     *
1212     * @param string $a_type type
1213     */
1214    public function setGapAnalysisActualStatusModePerType($a_type, $a_cat_title = "")
1215    {
1216        $this->gap_mode = "max_per_type";
1217        $this->gap_mode_type = $a_type;
1218        $this->gap_cat_title = $a_cat_title;
1219        $this->mode = "gap";
1220    }
1221
1222    /**
1223     * Set gap analysis actual status mode "per object"
1224     *
1225     * @param integer $a_obj_id object id
1226     */
1227    public function setGapAnalysisActualStatusModePerObject($a_obj_id, $a_cat_title = "")
1228    {
1229        $this->gap_mode = "max_per_object";
1230        $this->gap_mode_obj_id = $a_obj_id;
1231        $this->gap_cat_title = $a_cat_title;
1232        $this->mode = "gap";
1233    }
1234
1235    /**
1236     * Get actual levels
1237     *
1238     * @param array $skills
1239     * @param int $user_id
1240     */
1241    protected function getActualLevels($skills, $user_id)
1242    {
1243        // get actual levels for gap analysis
1244        $this->actual_levels = array();
1245        include_once("./Services/Skill/classes/class.ilBasicSkill.php");
1246        foreach ($skills as $sk) {
1247            $bs = new ilBasicSkill($sk["base_skill_id"]);
1248            if ($this->gap_mode == "max_per_type") {
1249                $max = $bs->getMaxLevelPerType($sk["tref_id"], $this->gap_mode_type, $user_id);
1250                $this->actual_levels[$sk["base_skill_id"]][$sk["tref_id"]] = $max;
1251            } elseif ($this->gap_mode == "max_per_object") {
1252                $max = $bs->getMaxLevelPerObject($sk["tref_id"], $this->gap_mode_obj_id, $user_id);
1253                $this->actual_levels[$sk["base_skill_id"]][$sk["tref_id"]] = $max;
1254            } else {
1255                $max = $bs->getMaxLevel($sk["tref_id"], $user_id);
1256                $this->actual_levels[$sk["base_skill_id"]][$sk["tref_id"]] = $max;
1257            }
1258        }
1259    }
1260
1261
1262    /**
1263     * Get gap analysis html
1264     *
1265     * @param
1266     * @param array $a_skills deprecated, use setObjectSkills and listProfiles instead
1267     * @return
1268     */
1269    public function getGapAnalysisHTML($a_user_id = 0, $a_skills = null)
1270    {
1271        $ilUser = $this->user;
1272        $lng = $this->lng;
1273
1274
1275        if ($a_skills == null) {
1276            $a_skills = $this->obj_skills;
1277        }
1278
1279        include_once("./Services/UIComponent/Panel/classes/class.ilPanelGUI.php");
1280
1281        if ($this->getIntroText() != "") {
1282            $pan = ilPanelGUI::getInstance();
1283            $pan->setPanelStyle(ilPanelGUI::PANEL_STYLE_PRIMARY);
1284            $pan->setBody($this->getIntroText());
1285            $intro_html = $pan->getHTML();
1286        }
1287
1288        //		$this->setTabs("list_skills");
1289
1290        if ($a_user_id == 0) {
1291            $user_id = $ilUser->getId();
1292        } else {
1293            $user_id = $a_user_id;
1294        }
1295
1296        $skills = array();
1297        if ($this->getProfileId() > 0) {
1298            $profile = new ilSkillProfile($this->getProfileId());
1299            $this->profile_levels = $profile->getSkillLevels();
1300
1301            foreach ($this->profile_levels as $l) {
1302                $skills[] = array(
1303                    "base_skill_id" => $l["base_skill_id"],
1304                    "tref_id" => $l["tref_id"],
1305                    "level_id" => $l["level_id"]
1306                    );
1307            }
1308        } elseif (is_array($a_skills)) {
1309            $skills = $a_skills;
1310        }
1311
1312        // get actual levels for gap analysis
1313        $this->getActualLevels($skills, $user_id);
1314
1315        $incl_self_eval = false;
1316        if (count($this->getGapAnalysisSelfEvalLevels()) > 0) {
1317            $incl_self_eval = true;
1318            $self_vals = $this->getGapAnalysisSelfEvalLevels();
1319        }
1320
1321        // output spider stuff
1322        $all_chart_html = "";
1323
1324        // determine skills that should be shown in the spider web
1325        $sw_skills = array();
1326        foreach ($skills as $sk) {
1327            if (!in_array($sk["base_skill_id"] . ":" . $sk["tref_id"], $this->hidden_skills)) {
1328                $sw_skills[] = $sk;
1329            }
1330        }
1331
1332        if (count($sw_skills) >= 3) {
1333            $skill_packages = array();
1334
1335            if (count($sw_skills) < 8) {
1336                $skill_packages[1] = $sw_skills;
1337            } else {
1338                $mod = count($sw_skills) % 7;
1339                $pkg_num = floor((count($sw_skills) - 1) / 7) + 1;
1340                $cpkg = 1;
1341                foreach ($sw_skills as $k => $s) {
1342                    $skill_packages[$cpkg][$k] = $s;
1343                    if ($mod < 3 && count($skill_packages) == ($pkg_num - 1) && count($skill_packages[$cpkg]) == 3 + $mod) {
1344                        $cpkg += 1;
1345                    } elseif (count($skill_packages[$cpkg]) == 7) {
1346                        $cpkg += 1;
1347                    }
1348                }
1349            }
1350
1351            $pkg_cnt = 0;
1352            foreach ($skill_packages as $pskills) {
1353                $pkg_cnt++;
1354                $max_cnt = 0;
1355                $leg_labels = array();
1356                //var_dump($this->profile_levels);
1357                //foreach ($this->profile_levels as $k => $l)
1358
1359                // write target, actual and self counter to skill array
1360                foreach ($pskills as $k => $l) {
1361                    //$bs = new ilBasicSkill($l["base_skill_id"]);
1362                    $bs = new ilBasicSkill($l["base_skill_id"]);
1363                    $leg_labels[] = ilBasicSkill::_lookupTitle($l["base_skill_id"], $l["tref_id"]);
1364                    $levels = $bs->getLevelData();
1365                    $cnt = 0;
1366                    foreach ($levels as $lv) {
1367                        $cnt++;
1368                        if ($l["level_id"] == $lv["id"]) {
1369                            $pskills[$k]["target_cnt"] = $cnt;
1370                        }
1371                        if ($this->actual_levels[$l["base_skill_id"]][$l["tref_id"]] == $lv["id"]) {
1372                            $pskills[$k]["actual_cnt"] = $cnt;
1373                        }
1374                        if ($incl_self_eval) {
1375                            if ($self_vals[$l["base_skill_id"]][$l["tref_id"]] == $lv["id"]) {
1376                                $pskills[$k]["self_cnt"] = $cnt;
1377                            }
1378                        }
1379                        $max_cnt = max($max_cnt, $cnt);
1380                    }
1381                }
1382
1383                include_once("./Services/Chart/classes/class.ilChart.php");
1384                $chart = ilChart::getInstanceByType(ilChart::TYPE_SPIDER, "gap_chart" . $pkg_cnt);
1385                $chart->setsize(800, 300);
1386                $chart->setYAxisMax($max_cnt);
1387                $chart->setLegLabels($leg_labels);
1388
1389                // target level
1390                $cd = $chart->getDataInstance();
1391                $cd->setLabel($lng->txt("skmg_target_level"));
1392                $cd->setFill(true, "#A0A0A0");
1393
1394                // other users
1395                $cd2 = $chart->getDataInstance();
1396                if ($this->gap_cat_title != "") {
1397                    $cd2->setLabel($this->gap_cat_title);
1398                } elseif ($this->gap_mode == "max_per_type") {
1399                    $cd2->setLabel($lng->txt("objs_" . $this->gap_mode_type));
1400                } elseif ($this->gap_mode == "max_per_object") {
1401                    $cd2->setLabel(ilObject::_lookupTitle($this->gap_mode_obj_id));
1402                }
1403                //$cd2->setFill(true, "#dcb496");
1404                $cd2->setFill(true, "#FF8080");
1405                $cd2->setFill(true, "#cc8466");
1406
1407                // self evaluation
1408                if ($incl_self_eval) {
1409                    $cd3 = $chart->getDataInstance();
1410                    $cd3->setLabel($lng->txt("skmg_self_evaluation"));
1411                    $cd3->setFill(true, "#6ea03c");
1412                }
1413
1414                // fill in data
1415                $cnt = 0;
1416                foreach ($pskills as $pl) {
1417                    $cd->addPoint($cnt, (int) $pl["target_cnt"]);
1418                    $cd2->addPoint($cnt, (int) $pl["actual_cnt"]);
1419                    if ($incl_self_eval) {
1420                        $cd3->addPoint($cnt, (int) $pl["self_cnt"]);
1421                    }
1422                    $cnt++;
1423                }
1424
1425                // add data to chart
1426                if ($this->getProfileId() > 0) {
1427                    $chart->addData($cd);
1428                }
1429                $chart->addData($cd2);
1430                if ($incl_self_eval && count($this->getGapAnalysisSelfEvalLevels()) > 0) {
1431                    $chart->addData($cd3);
1432                }
1433
1434                if ($pkg_cnt == 1) {
1435                    $lg = new ilChartLegend();
1436                    $chart->setLegend($lg);
1437                }
1438
1439                $chart_html = $chart->getHTML();
1440                $all_chart_html .= $chart_html;
1441            }
1442
1443            $pan = ilPanelGUI::getInstance();
1444            $pan->setPanelStyle(ilPanelGUI::PANEL_STYLE_PRIMARY);
1445            $pan->setBody($all_chart_html);
1446            $all_chart_html = $pan->getHTML();
1447        }
1448
1449        $stree = new ilSkillTree();
1450        $html = "";
1451
1452        // order skills per virtual skill tree
1453        include_once("./Services/Skill/classes/class.ilVirtualSkillTree.php");
1454        $vtree = new ilVirtualSkillTree();
1455        $skills = $vtree->getOrderedNodeset($skills, "base_skill_id", "tref_id");
1456        foreach ($skills as $s) {
1457            $path = $stree->getSkillTreePath($s["base_skill_id"]);
1458
1459            // check draft
1460            foreach ($path as $p) {
1461                if ($p["status"] == ilSkillTreeNode::STATUS_DRAFT) {
1462                    continue(2);
1463                }
1464            }
1465            $html .= $this->getSkillHTML($s["base_skill_id"], $user_id, false, $s["tref_id"]);
1466        }
1467
1468        // list skills
1469        //		include_once("./Services/Skill/classes/class.ilPersonalSkillTableGUI.php");
1470        //		$sktab = new ilPersonalSkillTableGUI($this, "listSkills");
1471
1472        return $intro_html . $all_chart_html . $html;
1473    }
1474
1475    /**
1476     * Select profile
1477     *
1478     * @param
1479     */
1480    public function selectProfile()
1481    {
1482        $ilCtrl = $this->ctrl;
1483
1484        $ilCtrl->setParameter($this, "profile_id", $_POST["profile_id"]);
1485        if ($this->mode == "gap") {
1486            $ilCtrl->redirect($this, "listProfilesForGap");
1487        } else {
1488            $ilCtrl->redirect($this, "listAssignedProfile");
1489        }
1490    }
1491
1492    /**
1493     * Get materials
1494     *
1495     * @param
1496     * @return string
1497     */
1498    public function getMaterials($a_levels, $a_tref_id = 0, $a_user_id = 0)
1499    {
1500        $ilUser = $this->user;
1501        $lng = $this->lng;
1502
1503        if ($a_user_id == 0) {
1504            $a_user_id = $ilUser->getId();
1505        }
1506
1507        // only render, if materials given
1508        $got_mat = false;
1509        foreach ($a_levels as $v) {
1510            $mat_cnt = ilPersonalSkill::countAssignedMaterial(
1511                $a_user_id,
1512                $a_tref_id,
1513                $v["id"]
1514            );
1515            if ($mat_cnt > 0) {
1516                $got_mat = true;
1517            }
1518        }
1519        if (!$got_mat) {
1520            return "";
1521        }
1522
1523        $tpl = new ilTemplate("tpl.skill_materials.html", true, true, "Services/Skill");
1524        foreach ($a_levels as $k => $v) {
1525            $got_mat = false;
1526            foreach (ilPersonalSkill::getAssignedMaterial(
1527                $a_user_id,
1528                $a_tref_id,
1529                $v["id"]
1530            ) as $item) {
1531                $tpl->setCurrentBlock("material");
1532                $mat_data = $this->getMaterialInfo($item["wsp_id"], $a_user_id);
1533                $tpl->setVariable("HREF_LINK", $mat_data[1]);
1534                $tpl->setVariable("TXT_LINK", $mat_data[0]);
1535                $tpl->parseCurrentBlock();
1536                $got_mat = true;
1537            }
1538            if ($got_mat) {
1539                $tpl->setCurrentBlock("level");
1540                $tpl->setVariable("LEVEL_VAL", $v["title"]);
1541                $tpl->parseCurrentBlock();
1542            }
1543        }
1544        $tpl->setVariable("TXT_MATERIAL", $lng->txt("skmg_materials"));
1545
1546        return $tpl->get();
1547    }
1548
1549    /**
1550     * Get profile target item
1551     *
1552     * @param
1553     * @return
1554     */
1555    public function getProfileTargetItem($a_profile_id, $a_levels, $a_tref_id = 0)
1556    {
1557        $lng = $this->lng;
1558
1559        $profile = new ilSkillProfile($a_profile_id);
1560        $profile_levels = $profile->getSkillLevels();
1561
1562        $a_activated_levels = array();
1563
1564        foreach ($a_levels as $k => $v) {
1565            foreach ($profile_levels as $pl) {
1566                if ($pl["level_id"] == $v["id"] &&
1567                    $pl["base_skill_id"] == $v["skill_id"] &&
1568                    $a_tref_id == $pl["tref_id"]) {
1569                    $a_activated_levels[] = $pl["level_id"];
1570                }
1571            }
1572        }
1573
1574        $tpl = new ilTemplate("tpl.skill_eval_item.html", true, true, "Services/Skill");
1575        $tpl->setVariable("SCALE_BAR", $this->getScaleBar($a_levels, $a_activated_levels));
1576
1577        $tpl->setVariable("TYPE", $lng->txt("skmg_target_level"));
1578        $tpl->setVariable("TITLE", "");
1579
1580        return $tpl->get();
1581    }
1582
1583    /**
1584     *
1585     *
1586     * @param
1587     * @return
1588     */
1589    public function getActualGapItem($a_levels, $a_tref_id = 0)
1590    {
1591        $lng = $this->lng;
1592
1593        $a_activated_levels = array();
1594        foreach ($a_levels as $k => $v) {
1595            if ($this->actual_levels[$v["skill_id"]][$a_tref_id] == $v["id"]) {
1596                $a_activated_levels[] = $v["id"];
1597            }
1598        }
1599
1600        if ($this->gap_cat_title != "") {
1601            $title = $this->gap_cat_title;
1602        } elseif ($this->gap_mode == "max_per_type") {
1603            $title = $lng->txt("objs_" . $this->gap_mode_type);
1604        } elseif ($this->gap_mode == "max_per_object") {
1605            $title = ilObject::_lookupTitle($this->gap_mode_obj_id);
1606        }
1607
1608        $tpl = new ilTemplate("tpl.skill_eval_item.html", true, true, "Services/Skill");
1609        $tpl->setVariable("SCALE_BAR", $this->getScaleBar($a_levels, $a_activated_levels));
1610
1611        $type = 1;
1612        $tpl->setVariable("TYPE", $lng->txt("skmg_eval_type_" . $type));
1613        if ($type > 0) {
1614            $tpl->touchBlock("st" . $type);
1615            $tpl->touchBlock("stb" . $type);
1616        }
1617
1618        if ($title != $lng->txt("skmg_eval_type_" . $type)) {
1619            $tpl->setVariable("TITLE", $title);
1620        }
1621
1622        return $tpl->get();
1623    }
1624
1625    /**
1626     *
1627     *
1628     * @param
1629     * @return
1630     */
1631    public function getSelfEvalGapItem($a_levels, $a_tref_id = 0)
1632    {
1633        $lng = $this->lng;
1634
1635        $self_vals = $this->getGapAnalysisSelfEvalLevels();
1636        if (count($self_vals) == 0) {
1637            return;
1638        }
1639
1640        $a_activated_levels = array();
1641        foreach ($a_levels as $k => $v) {
1642            if ($self_vals[$v["skill_id"]][$a_tref_id] == $v["id"]) {
1643                $a_activated_levels[] = $v["id"];
1644            }
1645        }
1646
1647        $tpl = new ilTemplate("tpl.skill_eval_item.html", true, true, "Services/Skill");
1648        $tpl->setVariable("SCALE_BAR", $this->getScaleBar($a_levels, $a_activated_levels));
1649
1650        $type = 3;
1651        $tpl->setVariable("TYPE", $lng->txt("skmg_eval_type_" . $type));
1652        if ($type > 0) {
1653            $tpl->touchBlock("st" . $type);
1654            $tpl->touchBlock("stb" . $type);
1655        }
1656
1657        return $tpl->get();
1658    }
1659
1660
1661    /**
1662     * Get scale bar
1663     *
1664     * @param
1665     * @return
1666     */
1667    public function getScaleBar($a_levels, $a_activated_levels)
1668    {
1669        $vals = array();
1670
1671        if (!is_array($a_activated_levels)) {
1672            $a_activated_levels = array($a_activated_levels);
1673        }
1674
1675        foreach ($a_levels as $level) {
1676            $vals[$level["title"]] = (in_array($level["id"], $a_activated_levels));
1677        }
1678        $scale_bar = $this->ui_fac->chart()->scaleBar($vals);
1679
1680        return $this->ui_ren->render($scale_bar);
1681    }
1682
1683    /**
1684     * Get eval item
1685     *
1686     * @param
1687     * @return
1688     */
1689    public function getEvalItem($a_levels, $a_level_entry)
1690    {
1691        $lng = $this->lng;
1692        $ilAccess = $this->access;
1693
1694        $tpl = new ilTemplate("tpl.skill_eval_item.html", true, true, "Services/Skill");
1695        $tpl->setVariable("SCALE_BAR", $this->getScaleBar($a_levels, $a_level_entry["level_id"]));
1696
1697        include_once("./Services/Skill/classes/class.ilSkillEval.php");
1698        $type = ilSkillEval::TYPE_APPRAISAL;
1699
1700        if ($a_level_entry["self_eval"] == 1) {
1701            $type = ilSkillEval::TYPE_SELF_EVAL;
1702        }
1703
1704        if ($a_level_entry["trigger_obj_type"] == "tst") {
1705            $type = ilSkillEval::TYPE_MEASUREMENT;
1706        }
1707
1708        ilDatePresentation::setUseRelativeDates(false);
1709        $title = ($a_level_entry["trigger_obj_id"] > 0)
1710                ? $a_level_entry["trigger_title"]
1711                : "";
1712
1713        if ($a_level_entry["trigger_ref_id"] > 0
1714            && $ilAccess->checkAccess("read", "", $a_level_entry["trigger_ref_id"])) {
1715            include_once("./Services/Link/classes/class.ilLink.php");
1716            $title = "<a href='" . ilLink::_getLink($a_level_entry["trigger_ref_id"]) . "'>" . $title . "</a>";
1717        }
1718
1719        $tpl->setVariable("TYPE", $lng->txt("skmg_eval_type_" . $type));
1720        if ($type > 0) {
1721            $tpl->touchBlock("st" . $type);
1722            $tpl->touchBlock("stb" . $type);
1723        }
1724        $tpl->setVariable("TITLE", $title);
1725        $tpl->setVariable(
1726            "DATE",
1727            ilDatePresentation::formatDate(new ilDate($a_level_entry["status_date"], IL_CAL_DATETIME))
1728        );
1729
1730        ilDatePresentation::setUseRelativeDates(true);
1731
1732        return $tpl->get();
1733    }
1734
1735    /**
1736     * Get level description
1737     *
1738     * @param
1739     * @return
1740     */
1741    public function getSkillDescription($skill)
1742    {
1743        $level_data = $skill->getLevelData();
1744        $tpl = new ilTemplate("tpl.skill_desc.html", true, true, "Services/Skill");
1745
1746        $desc_exists = false;
1747        foreach ($level_data as $l) {
1748            if ($l["description"] != "") {
1749                $desc_exists = true;
1750            }
1751        }
1752        reset($level_data);
1753        if ($desc_exists) {
1754            foreach ($level_data as $l) {
1755                $tpl->setCurrentBlock("level");
1756                $tpl->setVariable("LEVEL_VAL", $l["title"]);
1757                $tpl->setVariable("LEVEL_DESC", nl2br($l["description"]));
1758                $tpl->parseCurrentBlock();
1759            }
1760        }
1761
1762        return $tpl->get();
1763    }
1764
1765    /**
1766     * Render suggested resources
1767     *
1768     * @param
1769     * @return
1770     */
1771    public function getSuggestedResources($a_profile_id, $a_levels, $a_base_skill, $a_tref_id)
1772    {
1773        $lng = $this->lng;
1774
1775        $tpl = new ilTemplate("tpl.suggested_resources.html", true, true, "Services/Skill");
1776
1777        // use a profile
1778        if ($a_profile_id > 0) {
1779            $too_low = true;
1780            $current_target_level = 0;
1781
1782            foreach ($a_levels as $k => $v) {
1783                foreach ($this->profile_levels as $pl) {
1784                    if ($pl["level_id"] == $v["id"] &&
1785                        $pl["base_skill_id"] == $v["skill_id"]) {
1786                        $too_low = true;
1787                        $current_target_level = $v["id"];
1788                    }
1789                }
1790
1791                if ($this->actual_levels[$v["skill_id"]][$a_tref_id] == $v["id"]) {
1792                    $too_low = false;
1793                }
1794            }
1795
1796            // suggested resources
1797            if ($too_low) {
1798                include_once("./Services/Skill/classes/class.ilSkillResources.php");
1799                $skill_res = new ilSkillResources($a_base_skill, $a_tref_id);
1800                $res = $skill_res->getResources();
1801                $imp_resources = array();
1802                foreach ($res as $level) {
1803                    foreach ($level as $r) {
1804                        if ($r["imparting"] == true &&
1805                            $current_target_level == $r["level_id"]) {
1806                            $imp_resources[] = $r;
1807                        }
1808                    }
1809                }
1810                foreach ($imp_resources as $r) {
1811                    $ref_id = $r["rep_ref_id"];
1812                    $obj_id = ilObject::_lookupObjId($ref_id);
1813                    $title = ilObject::_lookupTitle($obj_id);
1814                    include_once("./Services/Link/classes/class.ilLink.php");
1815                    $tpl->setCurrentBlock("resource_item");
1816                    $tpl->setVariable("TXT_RES", $title);
1817                    $tpl->setVariable("HREF_RES", ilLink::_getLink($ref_id));
1818                    $tpl->parseCurrentBlock();
1819                }
1820                if (count($imp_resources) > 0) {
1821                    $tpl->touchBlock("resources_list");
1822                    $tpl->setVariable("SUGGESTED_MAT_MESS", $lng->txt("skmg_skill_needs_impr_res"));
1823                    return $tpl->get();
1824                } else {
1825                    $tpl->setVariable("SUGGESTED_MAT_MESS", $lng->txt("skmg_skill_needs_impr_no_res"));
1826                    return $tpl->get();
1827                }
1828            } else {
1829                $tpl->setVariable("SUGGESTED_MAT_MESS", $lng->txt("skmg_skill_no_needs_impr"));
1830                return $tpl->get();
1831            }
1832        } else {
1833            // no profile, just list all resources
1834            include_once("./Services/Skill/classes/class.ilSkillResources.php");
1835            $skill_res = new ilSkillResources($a_base_skill, $a_tref_id);
1836            $res = $skill_res->getResources();
1837            // add $r["level_id"] info
1838            $any = false;
1839            foreach ($res as $level) {
1840                $available = false;
1841                $cl = 0;
1842                foreach ($level as $r) {
1843                    if ($r["imparting"]) {
1844                        $ref_id = $r["rep_ref_id"];
1845                        $obj_id = ilObject::_lookupObjId($ref_id);
1846                        $title = ilObject::_lookupTitle($obj_id);
1847                        include_once("./Services/Link/classes/class.ilLink.php");
1848                        $tpl->setCurrentBlock("resource_item");
1849                        $tpl->setVariable("TXT_RES", $title);
1850                        $tpl->setVariable("HREF_RES", ilLink::_getLink($ref_id));
1851                        $tpl->parseCurrentBlock();
1852                        $available = true;
1853                        $any = true;
1854                        $cl = $r["level_id"];
1855                    }
1856                }
1857                if ($available) {
1858                    $tpl->setCurrentBlock("resources_list_level");
1859                    $tpl->setVariable("TXT_LEVEL", $lng->txt("skmg_level"));
1860                    $tpl->setVariable("LEVEL_NAME", ilBasicSkill::lookupLevelTitle($cl));
1861                    $tpl->parseCurrentBlock();
1862                    $tpl->touchBlock("resources_list");
1863                }
1864            }
1865            if ($any) {
1866                $tpl->setVariable("SUGGESTED_MAT_MESS", $lng->txt("skmg_suggested_resources"));
1867                return $tpl->get();
1868            }
1869        }
1870        return "";
1871    }
1872
1873    /**
1874     * List profile
1875     *
1876     * @param
1877     * @return
1878     */
1879    public function listAssignedProfile()
1880    {
1881        $ilCtrl = $this->ctrl;
1882
1883        $main_tpl = $this->tpl;
1884
1885        $tpl = new ilTemplate("tpl.skill_filter.html", true, true, "Services/Skill");
1886
1887        $this->setTabs("profile");
1888
1889        $this->determineCurrentProfile();
1890        $this->showProfileSelectorToolbar();
1891
1892        $filter_toolbar = new ilToolbarGUI();
1893        $filter_toolbar->setFormAction($ilCtrl->getFormAction($this));
1894        $this->getFilter()->addToToolbar($filter_toolbar, true);
1895
1896        $skills = array();
1897        if ($this->getProfileId() > 0) {
1898            $profile = new ilSkillProfile($this->getProfileId());
1899            $this->profile_levels = $profile->getSkillLevels();
1900
1901            foreach ($this->profile_levels as $l) {
1902                $skills[] = array(
1903                    "base_skill_id" => $l["base_skill_id"],
1904                    "tref_id" => $l["tref_id"],
1905                    "level_id" => $l["level_id"]
1906                );
1907            }
1908        }
1909
1910        $this->getActualLevels($skills, $this->user->getId());
1911
1912        // render
1913        $html = "";
1914        foreach ($skills as $s) {
1915            // todo draft check
1916            $html .= $this->getSkillHTML($s["base_skill_id"], 0, true, $s["tref_id"]);
1917        }
1918
1919        if ($html != "") {
1920            $filter_toolbar->addFormButton($this->lng->txt("skmg_refresh_view"), "applyFilterAssignedProfiles");
1921
1922            $tpl->setVariable("FILTER", $filter_toolbar->getHTML());
1923
1924            $html = $tpl->get() . $html;
1925        }
1926
1927        $main_tpl->setContent($html);
1928    }
1929}
1930