ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilLTIViewGUI.php
Go to the documentation of this file.
1<?php
2/*
3 +-----------------------------------------------------------------------------+
4 | ILIAS open source |
5 +-----------------------------------------------------------------------------+
6 | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7 | |
8 | This program is free software; you can redistribute it and/or |
9 | modify it under the terms of the GNU General Public License |
10 | as published by the Free Software Foundation; either version 2 |
11 | of the License, or (at your option) any later version. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 +-----------------------------------------------------------------------------+
22*/
23
25
36{
40 const CHECK_HTTP_REFERER = true;
41
45 private $dic = null;
46 private $user = null;
47 private $log = null;
48 private $link_dir = "";
49
53 public $lng = null;
54
55 public function __construct()
56 {
57 global $DIC;
58 $this->dic = $DIC;
59 $this->log = $this->dic->logger()->lti();
60 $this->lng = $this->dic->language();
61 $this->lng->loadLanguageModule('lti');
62 }
63
67 public function init()
68 {
69 $this->link_dir = (defined("ILIAS_MODULE")) ? "../" : "";
70 if ($this->isLTIUser())
71 {
72 $context = $this->dic->globalScreen()->tool()->context();
73 $context->claim()->lti();
74 $this->initGUI();
75 }
76 }
77
81 public static function getInstance()
82 {
83 global $DIC;
84 return $DIC["lti"];
85 }
86
91 private function isLTIUser()
92 {
93 if (!$this->dic->user() instanceof ilObjUser) {
94 return false;
95 }
96 return (strpos($this->dic->user()->getAuthMode(), 'lti_') === 0);
97 }
98
99 public function executeCommand()
100 {
101 global $ilCtrl;
102 $cmd = $ilCtrl->getCmd();
103 switch ($cmd) {
104 case 'exit':
105 $this->exitLti();
106 break;
107 }
108 }
109
110 public function isActive() : bool
111 {
112 return $this->isLTIUser();
113 }
114
115 public function initGUI()
116 {
117 $this->log->debug("initGUI");
118 $baseclass = strtolower($_GET['baseClass']);
119 $cmdclass = strtolower($_GET['cmdClass']);
120 switch ($baseclass)
121 {
122 case 'illtiroutergui' :
123 return;
124 break;
125 }
126 }
127
128 public function getContextId() {
129 global $ilLocator;
130
131 // forced lti_context_id for example request command in exitLTI
132 if (isset($_GET['lti_context_id']) && $_GET['lti_context_id'] !== '') {
133 $this->log->debug("find context_id by GET param: " . $_GET['lti_context_id']);
134 return $_GET['lti_context_id'];
135 }
136
137 $ref_id = $this->findEffectiveRefId();
138 $this->log->debug("Effective ref_id: ". $ref_id);
139 // context_id = ref_id in request
140 if (isset($_SESSION['lti_' . $ref_id . '_post_data'])) {
141 $this->log->debug("lti context session exists for " . $ref_id);
142 return $ref_id;
143 }
144
145 // sub item request
146 $this->log->debug("ref_id not exists as context_id, walking tree backwards to find a valid context_id");
147 $locator_items = $ilLocator->getItems();
148 if (is_array($locator_items) && count($locator_items) > 0) {
149 for ($i = count($locator_items)-1;$i>=0;$i--) {
150 if (isset($_SESSION['lti_' . $locator_items[$i]['ref_id'] . '_post_data'])) {
151 $this->log->debug("found valid ref_id in locator: " . $locator_items[$i]['ref_id']);
152 return $locator_items[$i]['ref_id'];
153 }
154 }
155 }
156 $this->log->warning("no valid context_id found for ref_id request: " . $ref_id);
157
159 $ref_id = '';
160 $obj_type = '';
161 $context_id = '';
162 $referer = '';
163
164 // first try to get real http referer
165 if (isset($_SERVER['HTTP_REFERER'])) {
166 $referer = $this->findEffectiveRefId($_SERVER['HTTP_REFERER']);
167 }
168 else { // only fallback and not reliable on multiple browser LTi contexts
169 if (isset($_SESSION['referer_ref_id'])) {
170 $referer = $_SESSION['referer_ref_id'];
171 }
172 }
173
174 if ($referer != '') {
175 if (isset($_SESSION['lti_' . $referer . '_post_data'])) {
176 $ref_id =$referer;
177 $context_id = $referer;
178 $obj_type = ilObject::_lookupType($ref_id,true);
179 $this->log->debug("referer obj_type: " . $obj_type);
180 }
181 else {
182 $this->log->debug("search tree of referer...");
183 if ($this->dic->repositoryTree()->isInTree($referer)) {
184 $path = $this->dic->repositoryTree()->getPathId($referer);
185 for ($i = count($path)-1;$i>=0;$i--) {
186 if (isset($_SESSION['lti_' . $path[$i] . '_post_data'])) {
187 // redirect to referer, because it is valid
188 $ref_id = $referer;
189 $context_id = $path[$i];
190 $obj_type = ilObject::_lookupType($ref_id,true);
191 break;
192 }
193 }
194 }
195 }
196 }
197 if ($ref_id != '' && $obj_type != '') {
198 if ((isset($_GET['baseClass']) && $_GET['baseClass'] === 'ilDashboardGUI')
199 && (isset($_GET['cmdClass']) && $_GET['cmdClass'] === 'ilpersonalprofilegui')) {
200 return $context_id;
201 }
202 ilUtil::sendFailure($this->lng->txt('permission_denied'),true);
203 $redirect = $this->link_dir."goto.php?target=".$obj_type."_".$ref_id."&lti_context_id=".$context_id;
204 $this->log->debug("redirect: " . $redirect);
205 ilUtil::redirect($redirect);
206 }
207 }
208 $lti_context_ids = $_SESSION['lti_context_ids'];
209 if (is_array($lti_context_ids) && count($lti_context_ids) > 0) {
210 if (count($lti_context_ids) == 1) {
211 $this->log->debug("using context_id from only LTI session");
212 return $lti_context_ids[0];
213 }
214 else {
215 $this->log->warning("Multiple LTI sessions exists. The context_id can not be clearly detected");
216 }
217 }
218 return '';
219 }
220
221 public function getPostData() {
222 $context_id = $this->getContextId();
223 if ($context_id == '') {
224 $this->log->warning("could not find any valid context_id!");
225 return null;
226 }
227 $post_data = $_SESSION['lti_' . $this->getContextId() . '_post_data'];
228 if (!is_array($post_data)) {
229 $this->log->warning("no session post_data: " . "lti_" . $this->getContextId() . "_post_data");
230 return null;
231 }
232 return $post_data;
233 }
234
235 public function getExternalCss() {
236 $post_data = $this->getPostData();
237 if ($post_data !== null) {
238 return (isset($post_data['launch_presentation_css_url'])) ? $post_data['launch_presentation_css_url'] : '';
239 }
240 return '';
241 }
242
243 public function getTitle() : string
244 {
245 $post_data = $this->getPostData();
246 if ($post_data !== null) {
247 return (isset($post_data['resource_link_title'])) ? "LTI - " . $post_data['resource_link_title'] : "LTI";
248 }
249 return "LTI";
250 }
251
252 public function getTitleForExitPage() : string
253 {
254 return $this->lng->txt('lti_exited');
255 }
256
257 public function getShortTitle() : string
258 {
259 return $this->lng->txt('lti_mode');
260 }
261
266 public function exitLti()
267 {
268 $this->dic->logger()->lti()->info("exitLTI");
269 $force_ilias_logout = false;
270 $context_id = $this->getContextId();
271 if ($context_id == '') {
272 $this->log->warning("could not find any valid context_id!");
273 $force_ilias_logout = true;
274 }
275 $post_data = $this->getPostData();
276 $return_url = ($post_data !== null) ? $post_data['launch_presentation_return_url'] : '';
277 $this->removeContextFromSession($context_id);
278
279 if (isset($_SESSION['lti_' . $context_id . '_post_data'])) {
280 unset($_SESSION['lti_' . $context_id . '_post_data']);
281 $this->dic->logger()->lti()->debug('unset SESSION["' . 'lti_' . $context_id . '_post_data"]');
282 }
283 if (!isset($return_url) || $return_url === '') {
284 $cc = $this->dic->globalScreen()->tool()->context()->current();
285 $cc->addAdditionalData(LtiViewLayoutProvider::GS_EXIT_LTI, true);
286 $ui_factory = $this->dic->ui()->factory();
287 $renderer = $this->dic->ui()->renderer();
288 $content = [
289 $ui_factory->messageBox()->info($this->lng->txt('lti_exited_info'))
290 ];
291 $tpl = $this->dic["tpl"];
292 $tpl->setContent($renderer->render($content));
293 $this->logout($force_ilias_logout);
294 $tpl->printToStdout();
295 } else {
296 $this->logout($force_ilias_logout);
297 header('Location: ' . $return_url);
298 }
299 }
300
304 public function logout($force_ilias_logout=false)
305 {
306 if ($force_ilias_logout) {
307 $this->log->warning("forcing logout ilias session, maybe a broken LTI context");
308 }
309 else {
310 if (is_array($_SESSION['lti_context_ids']) && count($_SESSION['lti_context_ids']) > 0) {
311 $this->log->debug("there is another valid consumer session: ilias session logout refused.");
312 return;
313 }
314 }
315 $this->dic->logger()->lti()->info("logout");
316 $GLOBALS['DIC']->user()->setAuthMode(AUTH_LOCAL);
317 //ilSession::setClosingContext(ilSession::SESSION_CLOSE_USER); // needed?
318 $auth = $GLOBALS['DIC']['ilAuthSession'];
319 //$auth->logout(); // needed?
320 $auth->setExpired($auth::SESSION_AUTH_EXPIRED,ilAuthStatus::STATUS_UNDEFINED);
321 session_destroy();
322 $client_id = $_COOKIE["ilClientId"];
323 ilUtil::setCookie("ilClientId", "");
324 ilUtil::setCookie("PHPSESSID","");
325 }
326
327 public function getCmdLink(String $cmd) : String
328 {
329 global $ilCtrl;
330 $lti_context_id = $this->getContextId();
331 $lti_context_id_param = ($lti_context_id != '') ? "&lti_context_id=".$lti_context_id : '';
332 $targetScript = ($ilCtrl->getTargetScript() !== 'ilias.php') ? "ilias.php" : "";
333 return $this->link_dir.$targetScript.$ilCtrl->getLinkTargetByClass(array('illtiroutergui',strtolower(get_class($this))),$cmd)."&baseClass=illtiroutergui".$lti_context_id_param;
334 }
335
336 private function getSessionValue(String $sess_key) : String
337 {
338 if (isset($_SESSION[$sess_key]) && $_SESSION[$sess_key] != '') {
339 return $_SESSION[$sess_key];
340 } else {
341 return '';
342 }
343 }
344
345 private function getCookieValue(String $cookie_key) : String
346 {
347 if (isset($_COOKIE[$cookie_key]) && $_COOKIE[$cookie_key] != '') {
348 return $_COOKIE[$cookie_key];
349 }
350 else {
351 return '';
352 }
353 }
354
355 private function removeContextFromSession($context_id) {
356 $lti_context_ids = $_SESSION['lti_context_ids'];
357 if (is_array($lti_context_ids) && in_array($context_id,$lti_context_ids)) {
358 array_splice($lti_context_ids,array_search($context_id,$lti_context_ids),1);
359 $_SESSION['lti_context_ids'] = $lti_context_ids;
360 }
361 }
362
366 private function findEffectiveRefId($url=null)
367 {
368 if ($url === null) {
369 $query = $_GET;
370 }
371 else {
372 parse_str(parse_url($url, PHP_URL_QUERY),$query);
373 }
374 if ((int) $query['ref_id']) {
375 return (int) $query['ref_id'];
376 }
377 $target_arr = explode('_', (string) $query['target']);
378 if (isset($target_arr[1]) and (int) $target_arr[1]) {
379 return (int) $target_arr[1];
380 }
381 return '';
382 }
383}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$_GET["client_id"]
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
const AUTH_LOCAL
@classDescription class for ILIAS ViewLTI
getCookieValue(String $cookie_key)
$dic
private variables
$lng
public variables
findEffectiveRefId($url=null)
Find effective ref_id for request.
getSessionValue(String $sess_key)
isLTIUser()
get LTI Mode from Users->getAuthMode
init()
Init LTI mode for lti authenticated users.
static getInstance()
for compatiblity with ilLTIRouterGUI
exitLti()
exit LTI session and if defined redirecting to returnUrl ToDo: Standard Template with delos ....
logout($force_ilias_logout=false)
logout ILIAS and destroys Session and ilClientId cookie if no consumer is still open in the LTI User ...
getCmdLink(String $cmd)
const CHECK_HTTP_REFERER
contstants
removeContextFromSession($context_id)
static _lookupType($a_id, $a_reference=false)
lookup object type
static setCookie($a_cookie_name, $a_cookie_value='', $a_also_set_super_global=true, $a_set_cookie_invalid=false)
static redirect($a_script)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
$target_arr
Definition: goto.php:47
global $ilCtrl
Definition: ilias.php:18
$client_id
$auth
Definition: metadata.php:59
$i
Definition: metadata.php:24
$query
$url
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
if(isset($_FILES['img_file']['size']) && $_FILES['img_file']['size'] > 0) $tpl
$context
Definition: webdav.php:26
$DIC
Definition: xapitoken.php:46
$_COOKIE[session_name()]
Definition: xapitoken.php:39