1<?php
2
3/* Copyright (c) 2015 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */
4
5
6/**
7 * Class ilObjStudyProgrammeIndividualPlanGUI
8 *
9 * @author: Richard Klees <richard.klees@concepts-and-training.de>
10 */
11
12class ilObjStudyProgrammeIndividualPlanGUI
13{
14    /**
15     * @var ilCtrl
16     */
17    public $ctrl;
18
19    /**
20     * @var ilTemplate
21     */
22    public $tpl;
23
24    /**
25     * @var ilObjStudyProgramme
26     */
27    public $object;
28
29    /**
30     * @var ilLng
31     */
32    public $lng;
33
34
35    /**
36     * @var ilObjUser
37     */
38    public $user;
39
40    protected $parent_gui;
41
42    /**
43     * @var ilStudyProgrammeUserProgressDB
44     */
45    protected $sp_user_progress_db;
46
47    public function __construct(
48        \ilGlobalTemplateInterface $tpl,
49        \ilCtrl $ilCtrl,
50        \ilLanguage $lng,
51        \ilObjUser $ilUser,
52        \ilAccess $ilAccess,
53        ilStudyProgrammeUserProgressDB $sp_user_progress_db,
54        ilStudyProgrammeUserAssignmentDB $sp_user_assignment_db
55    ) {
56        $this->tpl = $tpl;
57        $this->ctrl = $ilCtrl;
58        $this->lng = $lng;
59        $this->ilAccess = $ilAccess;
60        $this->user = $ilUser;
61
62        $this->assignment_object = null;
63
64        $this->sp_user_progress_db = $sp_user_progress_db;
65        $this->sp_user_assignment_db = $sp_user_assignment_db;
66
67        $this->object = null;
68
69        $lng->loadLanguageModule("prg");
70
71        $this->tpl->addCss("Modules/StudyProgramme/templates/css/ilStudyProgramme.css");
72    }
73
74    public function setParentGUI($a_parent_gui)
75    {
76        $this->parent_gui = $a_parent_gui;
77    }
78
79    public function setRefId($a_ref_id)
80    {
81        $this->ref_id = $a_ref_id;
82    }
83
84    public function executeCommand()
85    {
86        $cmd = $this->ctrl->getCmd();
87
88        if ($cmd == "") {
89            $cmd = "view";
90        }
91
92        switch ($cmd) {
93            case "view":
94            case "manage":
95            case "updateFromCurrentPlan":
96            case "updateFromInput":
97                $cont = $this->$cmd();
98                break;
99            default:
100                throw new ilException("ilObjStudyProgrammeMembersGUI: " .
101                                      "Command not supported: $cmd");
102        }
103
104        $this->tpl->setContent($cont);
105    }
106
107    protected function getAssignmentId()
108    {
109        if (!is_numeric($_GET["ass_id"])) {
110            throw new ilException("Expected integer 'ass_id'");
111        }
112        return (int) $_GET["ass_id"];
113    }
114
115    protected function getAssignmentObject()
116    {
117        if ($this->assignment_object === null) {
118            $id = $this->getAssignmentId();
119            $this->assignment_object = $this->sp_user_assignment_db->getInstanceById((int) $id);
120        }
121        return $this->assignment_object;
122    }
123
124    protected function view()
125    {
126        require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeIndividualPlanProgressListGUI.php");
127        $progress = $this->getAssignmentObject()->getRootProgress();
128        if (
129            $this->parent_gui->getStudyProgramme()->getAccessControlByOrguPositionsGlobal()
130            && !in_array($progress->getUserId(), $this->parent_gui->viewIndividualPlan())
131        ) {
132            throw new ilStudyProgrammePositionBasedAccessViolationException(
133                "may not access individua plan of user"
134            );
135        }
136        $gui = new ilStudyProgrammeIndividualPlanProgressListGUI($progress);
137        $gui->setOnlyRelevant(true);
138        // Wrap a frame around the original gui element to correct rendering.
139        $tpl = new ilTemplate("tpl.individual_plan_tree_frame.html", false, false, "Modules/StudyProgramme");
140        $tpl->setVariable("CONTENT", $gui->getHTML());
141        return $this->buildFrame("view", $tpl->get());
142    }
143
144
145    protected function manage()
146    {
147        require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeIndividualPlanTableGUI.php");
148        $ass = $this->getAssignmentObject();
149        if (
150            $this->parent_gui->getStudyProgramme()->getAccessControlByOrguPositionsGlobal()
151            && !in_array($ass->getUserId(), $this->parent_gui->editIndividualPlan())
152        ) {
153            throw new ilStudyProgrammePositionBasedAccessViolationException(
154                "may not access individua plan of user"
155            );
156        }
157        $this->ctrl->setParameter($this, "ass_id", $ass->getId());
158        $this->ctrl->setParameter($this, "cmd", "manage");
159        $table = new ilStudyProgrammeIndividualPlanTableGUI($this, $ass, $this->sp_user_progress_db);
160        $frame = $this->buildFrame("manage", $table->getHTML());
161        $this->ctrl->setParameter($this, "ass_id", null);
162        return $frame;
163    }
164
165    protected function updateFromCurrentPlan()
166    {
167        $ass = $this->getAssignmentObject();
168        if (
169            $this->parent_gui->getStudyProgramme()->getAccessControlByOrguPositionsGlobal()
170            && !in_array($ass->getUserId(), $this->parent_gui->editIndividualPlan())
171        ) {
172            throw new ilStudyProgrammePositionBasedAccessViolationException(
173                "may not access individual plan of user"
174            );
175        }
176        $ass->updateFromProgram();
177        $ass->updateValidityFromProgram();
178        $ass->updateDeadlineFromProgram();
179
180        $this->ctrl->setParameter($this, "ass_id", $ass->getId());
181        $this->showSuccessMessage("update_from_plan_successful");
182        $this->ctrl->redirect($this, "manage");
183    }
184
185    protected function updateFromInput()
186    {
187        require_once("Modules/StudyProgramme/classes/class.ilStudyProgrammeUserProgress.php");
188
189        $changed = false;
190
191        $changed = $this->updateStatus();
192
193        $this->ctrl->setParameter($this, "ass_id", $this->getAssignmentId());
194        if ($changed) {
195            $this->showSuccessMessage("update_successful");
196        }
197        $this->ctrl->redirect($this, "manage");
198    }
199
200    protected function updateStatus()
201    {
202        $status_updates = $this->getManualStatusUpdates();
203        $changed = false;
204        foreach ($status_updates as $prgrs_id => $status) {
205            $prgrs = $this->sp_user_progress_db->getInstanceById($prgrs_id);
206            $cur_status = $prgrs->getStatus();
207            if (
208                $this->parent_gui->getStudyProgramme()->getAccessControlByOrguPositionsGlobal()
209                && !in_array($prgrs->getUserId(), $this->parent_gui->editIndividualPlan())
210            ) {
211                continue;
212            }
213            if ($status == self::MANUAL_STATUS_NONE && $cur_status == ilStudyProgrammeProgress::STATUS_ACCREDITED) {
214                $prgrs->unmarkAccredited($this->user->getId());
215                $changed = true;
216            } elseif ($status == self::MANUAL_STATUS_NONE && $cur_status == ilStudyProgrammeProgress::STATUS_NOT_RELEVANT) {
217                $prgrs->markRelevant($this->user->getId());
218                $changed = true;
219            } elseif ($status == self::MANUAL_STATUS_NOT_RELEVANT && $cur_status != ilStudyProgrammeProgress::STATUS_NOT_RELEVANT) {
220                $prgrs->markNotRelevant($this->user->getId());
221                $changed = true;
222            } elseif ($status == self::MANUAL_STATUS_ACCREDITED && $cur_status != ilStudyProgrammeProgress::STATUS_ACCREDITED) {
223                $prgrs->markAccredited($this->user->getId());
224                $changed = true;
225            }
226
227            $deadline = null;
228            if ($this->postContainDeadline()) {
229                $deadline = $this->updateDeadline($prgrs);
230            }
231
232            if ($cur_status == ilStudyProgrammeProgress::STATUS_IN_PROGRESS) {
233                $changed = $this->updateRequiredPoints($prgrs_id) || $changed;
234
235                if ($deadline !== null && $deadline->format('Y-m-d') < date("Y-m-d")) {
236                    $prgrs->markFailed($this->user->getId());
237                }
238            } elseif ($cur_status == ilStudyProgrammeProgress::STATUS_FAILED) {
239                if ($deadline === null || $deadline->format('Y-m-d') > date("Y-m-d")) {
240                    $prgrs->markNotFailed((int) $this->user->getId());
241                }
242            }
243        }
244        return $changed;
245    }
246
247    /**
248     * Updates current deadline
249     *
250     * @param ilStudyProgrammeUserProgress 	$prgrs
251     *
252     * @return DateTime
253     */
254    protected function updateDeadline(ilStudyProgrammeUserProgress $prgrs)
255    {
256        $deadline = $this->getDeadlineFromForm($prgrs->getId());
257        $prgrs->setDeadline($deadline);
258        $prgrs->updateProgress($this->user->getId());
259
260        return $deadline;
261    }
262
263    protected function updateRequiredPoints($prgrs_id)
264    {
265        $required_points = $this->getRequiredPointsUpdates($prgrs_id);
266        $changed = false;
267
268        $prgrs = $this->sp_user_progress_db->getInstanceById($prgrs_id);
269        $cur_status = $prgrs->getStatus();
270        if ($cur_status != ilStudyProgrammeProgress::STATUS_IN_PROGRESS) {
271            return false;
272        }
273
274        if ($required_points < 0) {
275            $required_points = 0;
276        }
277
278        if ($required_points == $prgrs->getAmountOfPoints()) {
279            return false;
280        }
281
282        $prgrs->setRequiredAmountOfPoints($required_points, $this->user->getId());
283        return true;
284    }
285
286    /**
287     * Get the deadline from form
288     *
289     * @param int 	$prgrs_id
290     *
291     * @return DateTime
292     */
293    protected function getDeadlineFromForm($prgrs_id)
294    {
295        $post_var = $this->getDeadlinePostVarTitle();
296        if (!$this->postContainDeadline()) {
297            throw new ilException("Expected array $post_var in POST");
298        }
299
300        $post_value = $_POST[$post_var];
301        $deadline = $post_value[$prgrs_id];
302
303        if ($deadline == "") {
304            return null;
305        }
306        return DateTime::createFromFormat('d.m.Y', $deadline);
307    }
308
309    /**
310     * Checks whether $_POST contains deadline
311     *
312     * @return bool
313     */
314    protected function postContainDeadline()
315    {
316        $post_var = $this->getDeadlinePostVarTitle();
317        if (array_key_exists($post_var, $_POST)) {
318            return true;
319        }
320        return false;
321    }
322
323    protected function showSuccessMessage($a_lng_var)
324    {
325        require_once("Services/Utilities/classes/class.ilUtil.php");
326        ilUtil::sendSuccess($this->lng->txt("prg_$a_lng_var"), true);
327    }
328
329    protected function getManualStatusUpdates()
330    {
331        $post_var = $this->getManualStatusPostVarTitle();
332        if (!array_key_exists($post_var, $_POST)) {
333            throw new ilException("Expected array $post_var in POST");
334        }
335        return $_POST[$post_var];
336    }
337
338    protected function getRequiredPointsUpdates($prgrs_id)
339    {
340        $post_var = $this->getRequiredPointsPostVarTitle();
341        if (!array_key_exists($post_var, $_POST)) {
342            throw new ilException("Expected array $post_var in POST");
343        }
344
345        $post_value = $_POST[$post_var];
346        return (int) $post_value[$prgrs_id];
347    }
348
349
350    protected function buildFrame($tab, $content)
351    {
352        $tpl = new ilTemplate("tpl.indivdual_plan_frame.html", true, true, "Modules/StudyProgramme");
353        $ass = $this->getAssignmentObject();
354        $ref_id = $ass->getStudyProgramme()->getRefId();
355        $user_id = $ass->getUserId();
356        $tpl->setVariable("USERNAME", ilObjUser::_lookupFullname($user_id));
357        $tabs = [];
358        if ($this->ilAccess->checkAccess("manage_members", "", $ref_id)) {
359            $tabs[] = 'view';
360            $tabs[] = 'manage';
361        }
362
363        if ($this->parent_gui->getStudyProgramme()->getAccessControlByOrguPositionsGlobal()) {
364            if (in_array($user_id, $this->parent_gui->viewIndividualPlan())) {
365                $tabs[] = 'view';
366            }
367            if (in_array($user_id, $this->parent_gui->editIndividualPlan())) {
368                $tabs[] = 'manage';
369            }
370        }
371
372        $tabs = array_unique($tabs);
373        foreach ($tabs as $_tab) {
374            $tpl->setCurrentBlock("sub_tab");
375            $tpl->setVariable("CLASS", $_tab == $tab ? "active" : "");
376            $tpl->setVariable("LINK", $this->getLinkTargetForSubTab($_tab, $ass->getId()));
377            $tpl->setVariable("TITLE", $this->lng->txt("prg_$_tab"));
378            $tpl->parseCurrentBlock();
379        }
380        $tpl->setVariable("CONTENT", $content);
381
382        return $tpl->get();
383    }
384
385    protected function getLinkTargetForSubTab($a_tab, $a_ass_id)
386    {
387        $this->ctrl->setParameter($this, "ass_id", $a_ass_id);
388        $lnk = $this->ctrl->getLinkTarget($this, $a_tab);
389        $this->ctrl->setParameter($this, "ass_id", null);
390        return $lnk;
391    }
392
393    public function appendIndividualPlanActions(ilTable2GUI $a_table)
394    {
395        $a_table->setFormAction($this->ctrl->getFormAction($this));
396        $a_table->addCommandButton("updateFromCurrentPlan", $this->lng->txt("prg_update_from_current_plan"));
397        $a_table->addCommandButton("updateFromInput", $this->lng->txt("save"));
398    }
399
400    const POST_VAR_STATUS = "status";
401    const POST_VAR_REQUIRED_POINTS = "required_points";
402    const POST_VAR_DEADLINE = "deadline";
403    const MANUAL_STATUS_NONE = 0;
404    const MANUAL_STATUS_NOT_RELEVANT = 1;
405    const MANUAL_STATUS_ACCREDITED = 2;
406
407    public function getManualStatusPostVarTitle()
408    {
409        return self::POST_VAR_STATUS;
410    }
411
412    public function getRequiredPointsPostVarTitle()
413    {
414        return self::POST_VAR_REQUIRED_POINTS;
415    }
416
417    public function getDeadlinePostVarTitle()
418    {
419        return self::POST_VAR_DEADLINE;
420    }
421
422    public function getManualStatusNone()
423    {
424        return self::MANUAL_STATUS_NONE;
425    }
426
427    public function getManualStatusNotRelevant()
428    {
429        return self::MANUAL_STATUS_NOT_RELEVANT;
430    }
431
432    public function getManualStatusAccredited()
433    {
434        return self::MANUAL_STATUS_ACCREDITED;
435    }
436
437    public function getLinkTargetView($a_ass_id)
438    {
439        $cl = "ilObjStudyProgrammeIndividualPlanGUI";
440        $this->ctrl->setParameterByClass($cl, "ass_id", $a_ass_id);
441        $link = $this->ctrl->getLinkTargetByClass($cl, "view");
442        $this->ctrl->setParameterByClass($cl, "ass_id", null);
443        return $link;
444    }
445}
446