1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5/**
6 * Learning module presentation linker
7 *
8 * @author killing@leifos.de
9 */
10class ilLMPresentationLinker implements \ILIAS\COPage\PageLinker
11{
12    const TARGET_GUI = "illmpresentationgui";
13
14    /**
15     * @var bool
16     */
17    protected $offline;
18
19    /**
20     * Constructor
21     */
22    public function __construct(
23        ilObjLearningModule $lm,
24        ilLMTree $lm_tree,
25        int $current_page,
26        int $ref_id,
27        string $lang,
28        string $back_pg,
29        string $from_pg,
30        bool $offline,
31        string $export_format,
32        bool $export_all_languages,
33        ilCtrl $ctrl = null
34    ) {
35        global $DIC;
36
37        $this->ctrl = is_null($ctrl)
38            ? $DIC->ctrl()
39            : $ctrl;
40
41        $this->lm_tree = $lm_tree;
42        $this->lm = $lm;
43        $this->current_page = $current_page;
44        $this->back_pg = $back_pg;
45        $this->from_page = $from_pg;
46        $this->export_all_languages = $export_all_languages;
47        $this->lang = $lang;
48        $this->requested_ref_id = $ref_id;
49        $this->offline = $offline;
50        $this->export_format = $export_format;
51    }
52
53    /**
54     * @inheritDoc
55     */
56    public function setOffline($offline = true)
57    {
58        $this->offline = $offline;
59    }
60
61    /**
62     * handles links for learning module presentation
63     */
64    public function getLink(
65        $a_cmd = "",
66        $a_obj_id = "",
67        $a_frame = "",
68        $a_type = "",
69        $a_back_link = "append",
70        $a_anchor = "",
71        $a_srcstring = ""
72    ) {
73        if ($a_cmd == "") {
74            $a_cmd = "layout";
75        }
76
77        // handling of free pages
78        $cur_page_id = $this->current_page;
79        $back_pg = $this->back_pg;
80        if ($a_obj_id != "" && !$this->lm_tree->isInTree($a_obj_id) && $cur_page_id != "" &&
81            $a_back_link == "append") {
82            if ($back_pg != "") {
83                $back_pg = $cur_page_id . ":" . $back_pg;
84            } else {
85                $back_pg = $cur_page_id;
86            }
87        } else {
88            if ($a_back_link == "reduce") {
89                $limpos = strpos($this->back_pg, ":");
90
91                if ($limpos > 0) {
92                    $back_pg = substr($back_pg, strpos($back_pg, ":") + 1);
93                } else {
94                    $back_pg = "";
95                }
96            } elseif ($a_back_link != "keep") {
97                $back_pg = "";
98            }
99        }
100
101        // handle online links
102        if (!$this->offline) {
103            if ($this->from_page == "") {
104                // added if due to #23216 (from page has been set in lots of usual navigation links)
105                if (!in_array($a_frame, array("", "_blank"))) {
106                    $this->ctrl->setParameterByClass(self::TARGET_GUI, "from_page", $cur_page_id);
107                }
108            } else {
109                // faq link on page (in faq frame) includes faq link on other page
110                // if added due to bug #11007
111                if (!in_array($a_frame, array("", "_blank"))) {
112                    $this->ctrl->setParameterByClass(self::TARGET_GUI, "from_page", $this->from_page);
113                }
114            }
115
116            if ($a_anchor != "") {
117                $this->ctrl->setParameterByClass(self::TARGET_GUI, "anchor", rawurlencode($a_anchor));
118            }
119            if ($a_srcstring != "") {
120                $this->ctrl->setParameterByClass(self::TARGET_GUI, "srcstring", $a_srcstring);
121            }
122            switch ($a_cmd) {
123                case "fullscreen":
124                    $link = $this->ctrl->getLinkTargetByClass(self::TARGET_GUI, "fullscreen", "", false, false);
125                    break;
126
127                case "sourcecodeDownload":
128                    $this->ctrl->setParameterByClass(self::TARGET_GUI, "obj_id", $a_obj_id);
129                    $link = $this->ctrl->getLinkTargetByClass([self::TARGET_GUI, "ilLMPageGUI"], "", "", false, false);
130                    break;
131
132                default:
133
134                    if ($back_pg != "") {
135                        $this->ctrl->setParameterByClass(self::TARGET_GUI, "back_pg", $back_pg);
136                    }
137                    if ($a_frame != "") {
138                        $this->ctrl->setParameterByClass(self::TARGET_GUI, "frame", $a_frame);
139                    }
140                    if ($a_obj_id != "") {
141                        switch ($a_type) {
142                            case "MediaObject":
143                                $this->ctrl->setParameterByClass(self::TARGET_GUI, "mob_id", $a_obj_id);
144                                break;
145
146                            default:
147                                $this->ctrl->setParameterByClass(self::TARGET_GUI, "obj_id", $a_obj_id);
148                                $link .= "&amp;obj_id=" . $a_obj_id;
149                                break;
150                        }
151                    }
152                    if ($a_type != "") {
153                        $this->ctrl->setParameterByClass(self::TARGET_GUI, "obj_type", $a_type);
154                    }
155                    $link = $this->ctrl->getLinkTargetByClass(
156                        self::TARGET_GUI,
157                        $a_cmd,
158                        $a_anchor,
159                        false,
160                        true
161                    );
162//					$link = str_replace("&", "&amp;", $link);
163
164                    $this->ctrl->setParameterByClass(self::TARGET_GUI, "frame", "");
165                    $this->ctrl->setParameterByClass(self::TARGET_GUI, "obj_id", "");
166                    $this->ctrl->setParameterByClass(self::TARGET_GUI, "mob_id", "");
167                    break;
168            }
169        } else {	// handle offline links
170            $lang_suffix = "";
171            if ($this->export_all_languages) {
172                if ($this->lang != "" && $this->lang != "-") {
173                    $lang_suffix = "_" . $this->lang;
174                }
175            }
176
177            switch ($a_cmd) {
178                case "downloadFile":
179                    break;
180
181                case "fullscreen":
182                    $link = "fullscreen.html";		// id is handled by xslt
183                    break;
184
185                case "layout":
186
187                    if ($a_obj_id == "") {
188                        $a_obj_id = $this->lm_tree->getRootId();
189                        $pg_node = $this->lm_tree->fetchSuccessorNode($a_obj_id, "pg");
190                        $a_obj_id = $pg_node["obj_id"];
191                    }
192                    if ($a_type == "StructureObject") {
193                        $pg_node = $this->lm_tree->fetchSuccessorNode($a_obj_id, "pg");
194                        $a_obj_id = $pg_node["obj_id"];
195                    }
196                    if ($a_frame != "" && $a_frame != "_blank") {
197                        if ($a_frame != "toc") {
198                            $link = "frame_" . $a_obj_id . "_" . $a_frame . $lang_suffix . ".html";
199                        } else {	// don't save multiple toc frames (all the same)
200                            $link = "frame_" . $a_frame . $lang_suffix . ".html";
201                        }
202                    } else {
203                        //if ($nid = ilLMObject::_lookupNID($this->lm->getId(), $a_obj_id, "pg"))
204                        if ($nid = ilLMPageObject::getExportId($this->lm->getId(), $a_obj_id)) {
205                            $link = "lm_pg_" . $nid . $lang_suffix . ".html";
206                        } else {
207                            $link = "lm_pg_" . $a_obj_id . $lang_suffix . ".html";
208                        }
209                    }
210                    break;
211
212                case "glossary":
213                    $link = "term_" . $a_obj_id . ".html";
214                    break;
215
216                case "media":
217                    $link = "media_" . $a_obj_id . ".html";
218                    break;
219
220                default:
221                    break;
222            }
223        }
224
225        $this->ctrl->clearParametersByClass(self::TARGET_GUI);
226
227        return $link;
228    }
229
230    public function getLayoutLinkTargets() : array
231    {
232        $targets = [
233            "New" => [
234                "Type" => "New",
235                "Frame" => "_blank",
236                "OnClick" => ""],
237            "FAQ" => [
238                "Type" => "FAQ",
239                "OnClick" => "return il.LearningModule.showContentFrame(event, 'faq');"],
240            "Glossary" => [
241                "Type" => "Glossary",
242                "OnClick" => "return il.LearningModule.showContentFrame(event, 'glossary');"],
243            "Media" => [
244                "Type" => "Media",
245                "OnClick" => "return il.LearningModule.showContentFrame(event, 'media');"]
246        ];
247
248        return $targets;
249    }
250
251    /**
252     * Get XMl for Link Targets
253     */
254    public function getLinkTargetsXML()
255    {
256        $link_info = "<LinkTargets>";
257        foreach ($this->getLayoutLinkTargets() as $k => $t) {
258            $link_info .= "<LinkTarget TargetFrame=\"" . $t["Type"] . "\" LinkTarget=\"" . $t["Frame"] . "\" OnClick=\"" . $t["OnClick"] . "\" />";
259        }
260        $link_info .= "</LinkTargets>";
261        return $link_info;
262    }
263
264    /**
265     * get xml for links
266     */
267    public function getLinkXML($a_int_links) : string
268    {
269        $ilCtrl = $this->ctrl;
270
271        $a_layoutframes = $this->getLayoutLinkTargets();
272
273        // Determine whether the view of a learning resource should
274        // be shown in the frameset of ilias, or in a separate window.
275        $showViewInFrameset = true;
276
277        if ($a_layoutframes == "") {
278            $a_layoutframes = array();
279        }
280        $link_info = "<IntLinkInfos>";
281        foreach ($a_int_links as $int_link) {
282            $target = $int_link["Target"];
283            if (substr($target, 0, 4) == "il__") {
284                $target_arr = explode("_", $target);
285                $target_id = $target_arr[count($target_arr) - 1];
286                $type = $int_link["Type"];
287                $targetframe = ($int_link["TargetFrame"] != "")
288                    ? $int_link["TargetFrame"]
289                    : "None";
290
291                // anchor
292                $anc = $anc_add = "";
293                if ($int_link["Anchor"] != "") {
294                    $anc = $int_link["Anchor"];
295                    $anc_add = "_" . rawurlencode($int_link["Anchor"]);
296                }
297                $lcontent = "";
298                switch ($type) {
299                    case "PageObject":
300                    case "StructureObject":
301                        $lm_id = ilLMObject::_lookupContObjID($target_id);
302                        if ($lm_id == $this->lm->getId() ||
303                            ($targetframe != "None" && $targetframe != "New")) {
304                            $ltarget = $a_layoutframes[$targetframe]["Frame"];
305                            $nframe = ($ltarget == "")
306                                ? ""
307                                : $ltarget;
308                            if ($ltarget == "") {
309                                if ($showViewInFrameset) {
310                                    $ltarget = "_parent";
311                                } else {
312                                    $ltarget = "_top";
313                                }
314                            }
315                            // scorm always in 1window view and link target
316                            // is always same frame
317                            if ($this->export_format == "scorm" &&
318                                $this->offline) {
319                                $ltarget = "";
320                            }
321                            $cmd = "layout";
322                            if ($nframe != "") {
323                                $cmd = "page";
324                            }
325                            $href =
326                                $this->getLink(
327                                    $cmd,
328                                    $target_id,
329                                    $nframe,
330                                    $type,
331                                    "append",
332                                    $anc
333                                );
334                            if ($lm_id == "") {
335                                $href = "";
336                            }
337                        } else {
338                            if (!$this->offline) {
339                                if ($type == "PageObject") {
340                                    $href = "./goto.php?target=pg_" . $target_id . $anc_add;
341                                } else {
342                                    $href = "./goto.php?target=st_" . $target_id;
343                                }
344                            } else {
345                                if ($type == "PageObject") {
346                                    $href = ILIAS_HTTP_PATH . "/goto.php?target=pg_" . $target_id . $anc_add . "&amp;client_id=" . CLIENT_ID;
347                                } else {
348                                    $href = ILIAS_HTTP_PATH . "/goto.php?target=st_" . $target_id . "&amp;client_id=" . CLIENT_ID;
349                                }
350                            }
351                            $ltarget = "";
352                            if ($targetframe == "New") {
353                                $ltarget = "_blank";
354                            }
355                        }
356                        break;
357
358                    case "GlossaryItem":
359                        if ($targetframe == "None") {
360                            $targetframe = "Glossary";
361                        }
362                        $ltarget = $a_layoutframes[$targetframe]["Frame"];
363                        $nframe = ($ltarget == "")
364                            ? $_GET["frame"]
365                            : $ltarget;
366                        $href =
367                            $this->getLink($a_cmd = "glossary", $target_id, $nframe, $type);
368                        break;
369
370                    case "MediaObject":
371                        $ltarget = $a_layoutframes[$targetframe]["Frame"];
372                        $nframe = ($ltarget == "")
373                            ? $_GET["frame"]
374                            : $ltarget;
375                        $href =
376                            $this->getLink($a_cmd = "media", $target_id, $nframe, $type);
377                        if ($this->offline) {
378                            $href = "media_" . $target_id . ".html";
379                        } else {
380                            $this->ctrl->setParameterByClass("illmpagegui", "mob_id", $target_id);
381                            $href = $this->ctrl->getLinkTargetByClass(
382                                "illmpagegui",
383                                "displayMedia",
384                                "",
385                                false,
386                                true
387                            );
388                            $this->ctrl->setParameterByClass("illmpagegui", "mob_id", "");
389                        }
390                        break;
391
392                    case "RepositoryItem":
393                        $obj_type = ilObject::_lookupType($target_id, true);
394                        $obj_id = ilObject::_lookupObjId($target_id);
395                        if (!$this->offline) {
396                            $href = "./goto.php?target=" . $obj_type . "_" . $target_id;
397                        } else {
398                            $href = ILIAS_HTTP_PATH . "/goto.php?target=" . $obj_type . "_" . $target_id . "&amp;client_id=" . CLIENT_ID;
399                        }
400                        $ltarget = ilFrameTargetInfo::_getFrame("MainContent");
401                        break;
402
403                    case "WikiPage":
404                        $href = ilWikiPage::getGotoForWikiPageTarget($target_id);
405                        break;
406
407                    case "File":
408                        if (!$this->offline) {
409                            $ilCtrl->setParameterByClass(self::TARGET_GUI, "obj_id", $this->current_page);
410                            $ilCtrl->setParameterByClass(self::TARGET_GUI, "file_id", "il__file_" . $target_id);
411                            $href = $ilCtrl->getLinkTargetByClass(
412                                self::TARGET_GUI,
413                                "downloadFile",
414                                "",
415                                false,
416                                true
417                            );
418                            $ilCtrl->setParameterByClass(self::TARGET_GUI, "file_id", "");
419                            $ilCtrl->setParameterByClass(self::TARGET_GUI, "obj_id", $_GET["obj_id"]);
420                        }
421                        break;
422
423                    case "User":
424                        $obj_type = ilObject::_lookupType($target_id);
425                        if ($obj_type == "usr") {
426                            $this->ctrl->setParameterByClass(self::TARGET_GUI, "obj_id", $this->current_page);
427                            $back = $this->ctrl->getLinkTargetByClass(
428                                self::TARGET_GUI,
429                                "layout",
430                                "",
431                                false,
432                                true
433                            );
434                            //var_dump($back); exit;
435                            $this->ctrl->setParameterByClass("ilpublicuserprofilegui", "user_id", $target_id);
436                            $this->ctrl->setParameterByClass(
437                                "ilpublicuserprofilegui",
438                                "back_url",
439                                rawurlencode($back)
440                            );
441                            $href = "";
442                            if (ilUserUtil::hasPublicProfile($target_id)) {
443                                $href = $this->ctrl->getLinkTargetByClass(
444                                    "ilpublicuserprofilegui",
445                                    "getHTML",
446                                    "",
447                                    false,
448                                    true
449                                );
450                            }
451                            $this->ctrl->setParameterByClass("ilpublicuserprofilegui", "user_id", "");
452                            $lcontent = ilUserUtil::getNamePresentation($target_id, false, false);
453                        }
454                        break;
455
456                }
457
458                $anc_par = 'Anchor="' . $anc . '"';
459
460                if ($href != "") {
461                    $link_info .= "<IntLinkInfo Target=\"$target\" Type=\"$type\" " .
462                        "TargetFrame=\"$targetframe\" LinkHref=\"$href\" LinkTarget=\"$ltarget\" LinkContent=\"$lcontent\" $anc_par/>";
463                }
464            }
465        }
466        $link_info .= "</IntLinkInfos>";
467
468        $link_info .= $this->getLinkTargetsXML();
469
470        return $link_info;
471    }
472
473    /**
474     * @inheritDoc
475     */
476    public function getFullscreenLink() : string
477    {
478        return $this->getLink("fullscreen");
479    }
480}
481