ILIAS  release_7 Revision v7.30-3-g800a261c036
XapiProxyPolyFill.php
Go to the documentation of this file.
1<?php
2 namespace XapiProxy;
3
5 {
6 protected $client;
7 protected $token;
8
9 protected $plugin;
10 protected $table_prefix;
11 protected $lrsType;
12 protected $authToken = null;
13 protected $objId = null;
14 protected $specificAllowedStatements = null;
15 protected $replacedValues = null;
16 protected $blockSubStatements = false;
17 protected $cmdParts;
18 protected $method;
19
20 protected $defaultLrsEndpoint = '';
21 protected $defaultLrsKey = '';
22 protected $defaultLrsSecret = '';
23
24 protected $fallbackLrsEndpoint = '';
25 protected $fallbackLrsKey = '';
26 protected $fallbackLrsSecret = '';
27
28 const PARTS_REG = '/^(.*?xapiproxy\.php)(\/([^?]+)?\??(.*))/';
29
30 protected $sniffVerbs = array(
31 "http://adlnet.gov/expapi/verbs/completed" => "completed",
32 "http://adlnet.gov/expapi/verbs/passed" => "passed",
33 "http://adlnet.gov/expapi/verbs/failed" => "failed",
34 "http://adlnet.gov/expapi/verbs/satisfied" => "passed"
35 );
36
37 const TERMINATED_VERB = "http://adlnet.gov/expapi/verbs/terminated";
38
39 public function __construct($client, $token, $plugin = false)
40 {
41 $this->client = $client;
42 $this->token = $token;
43 $this->plugin = $plugin;
44 if ($this->plugin) {
45 $this->table_prefix = "xxcf";
46 } else {
47 $this->table_prefix = "cmix";
48 }
49 preg_match(self::PARTS_REG, $GLOBALS['DIC']->http()->request()->getUri(), $this->cmdParts);
50 $this->method = strtolower($GLOBALS['DIC']->http()->request()->getMethod());
51 }
52
53 public function log()
54 {
55 global $log;
56 if ($this->plugin) {
57 return $log;
58 } else {
59 return \ilLoggerFactory::getLogger('cmix');
60 }
61 }
62
63 public function msg($msg)
64 {
65 if ($this->plugin) {
66 return "XapiCmi5Plugin: " . $msg;
67 } else {
68 return $msg;
69 }
70 }
71
72 public function initLrs()
73 {
74 $this->log()->debug($this->msg('initLrs'));
75 if ($this->plugin) {
76 require_once __DIR__ . '/../class.ilXapiCmi5LrsType.php';
77 require_once __DIR__ . '/../class.ilXapiCmi5AuthToken.php';
78 try {
79 $authToken = \ilXapiCmi5AuthToken::getInstanceByToken($this->token);
80 } catch (\ilXapiCmi5Exception $e) {
81 $this->log()->error($this->msg($e->getMessage()));
82 header('HTTP/1.1 401 Unauthorized');
83 header('Access-Control-Allow-Origin: ' . $_SERVER["HTTP_ORIGIN"]);
84 header('Access-Control-Allow-Credentials: true');
85 exit;
86 }
87 $this->authToken = $authToken;
88 $this->getLrsTypePlugin();
89 } else {
90 require_once __DIR__ . '/../class.ilCmiXapiLrsType.php';
91 require_once __DIR__ . '/../class.ilCmiXapiAuthToken.php';
92 try {
93 $authToken = \ilCmiXapiAuthToken::getInstanceByToken($this->token);
94 } catch (\ilCmiXapiException $e) {
95 $this->log()->error($this->msg($e->getMessage()));
96 header('HTTP/1.1 401 Unauthorized');
97 header('Access-Control-Allow-Origin: ' . $_SERVER["HTTP_ORIGIN"]);
98 header('Access-Control-Allow-Credentials: true');
99 exit;
100 }
101
102 $this->authToken = $authToken;
103 $this->getLrsType();
104 }
105 }
106
107 private function getLrsTypePlugin()
108 {
109 try {
110 $lrsType = $this->getLrsTypeAndMoreByToken();
111 if ($lrsType == null) {
112 // why not using $log?
113 $GLOBALS['DIC']->logger()->root()->log("XapiCmi5Plugin: 401 Unauthorized for token");
114 header('HTTP/1.1 401 Unauthorized');
115 header('Access-Control-Allow-Origin: ' . $_SERVER["HTTP_ORIGIN"]);
116 header('Access-Control-Allow-Credentials: true');
117 exit;
118 }
119 $this->defaultLrsEndpoint = $lrsType->getDefaultLrsEndpoint();
120 $this->defaultLrsKey = $lrsType->getDefaultLrsKey();
121 $this->defaultLrsSecret = $lrsType->getDefaultLrsSecret();
122
123 $this->fallbackLrsEndpoint = $lrsType->getFallbackLrsEndpoint();
124 $this->fallbackLrsKey = $lrsType->getFallbackLrsKey();
125 $this->fallbackLrsSecret = $lrsType->getFallbackLrsSecret();
126
127 $this->lrsType = $lrsType;
128 } catch (\Exception $e) {
129 // why not using $log?
130 $GLOBALS['DIC']->logger()->root()->log("XapiCmi5Plugin: " . $e->getMessage());
131 header('HTTP/1.1 401 Unauthorized');
132 header('Access-Control-Allow-Origin: ' . $_SERVER["HTTP_ORIGIN"]);
133 header('Access-Control-Allow-Credentials: true');
134 exit;
135 }
136 }
137
138
139 private function getLrsType()
140 { // Core new > 6
141 try {
142 $lrsType = $this->getLrsTypeAndMoreByToken();
143 $this->defaultLrsEndpoint = $lrsType->getLrsEndpoint();
144 $this->defaultLrsKey = $lrsType->getLrsKey();
145 $this->defaultLrsSecret = $lrsType->getLrsSecret();
146 $this->lrsType = $lrsType;
147 // one query IS better :-)
148 // $lrsType = new ilCmiXapiLrsType($authToken->getLrsTypeId());
149 $objId = $this->authToken->getObjId();
150 $this->objId = $objId;
151 if (!$lrsType->isAvailable()) {
152 throw new \ilCmiXapiException(
153 'lrs endpoint (id=' . $this->authToken->getLrsTypeId() . ') unavailable (responded 401-unauthorized)'
154 );
155 }
156 } catch (\ilCmiXapiException $e) {
157 $this->log()->error($this->msg($e->getMessage()));
158 header('Access-Control-Allow-Origin: ' . $_SERVER["HTTP_ORIGIN"]);
159 header('Access-Control-Allow-Credentials: true');
160 header('HTTP/1.1 401 Unauthorized');
161 exit;
162 }
163 \ilCmiXapiUser::saveProxySuccess($this->authToken->getObjId(), $this->authToken->getUsrId(), $this->lrsType->getPrivacyIdent());
164 return $lrsType;
165 }
169 private function getLrsTypeAndMoreByToken()
170 {
171 $type_id = null;
172 $lrs = null;
173 $db = $GLOBALS['DIC']->database();
174 $query = "SELECT {$this->table_prefix}_settings.lrs_type_id,
175 {$this->table_prefix}_settings.only_moveon,
176 {$this->table_prefix}_settings.achieved,
177 {$this->table_prefix}_settings.answered,
178 {$this->table_prefix}_settings.completed,
179 {$this->table_prefix}_settings.failed,
180 {$this->table_prefix}_settings.initialized,
181 {$this->table_prefix}_settings.passed,
182 {$this->table_prefix}_settings.progressed,
183 {$this->table_prefix}_settings.satisfied,
184 {$this->table_prefix}_settings.c_terminated,
185 {$this->table_prefix}_settings.hide_data,
186 {$this->table_prefix}_settings.c_timestamp,
187 {$this->table_prefix}_settings.duration,
188 {$this->table_prefix}_settings.no_substatements,
189 {$this->table_prefix}_settings.privacy_ident
190 FROM {$this->table_prefix}_settings, {$this->table_prefix}_token
191 WHERE {$this->table_prefix}_settings.obj_id = {$this->table_prefix}_token.obj_id AND {$this->table_prefix}_token.token = " . $db->quote($this->token, 'text');
192
193 $res = $db->query($query);
194 while ($row = $db->fetchObject($res)) {
195 $type_id = $row->lrs_type_id;
196 if ($type_id) {
197 $lrs = ($this->plugin) ? new \ilXapiCmi5LrsType($type_id) : new \ilCmiXapiLrsType($type_id);
198 }
199
200 $sarr = [];
201 if ((bool) $row->only_moveon) {
202 if ((bool) $row->achieved) {
203 $sarr[] = "https://w3id.org/xapi/dod-isd/verbs/achieved";
204 }
205 if ((bool) $row->answered) {
206 $sarr[] = "http://adlnet.gov/expapi/verbs/answered";
207 $sarr[] = "https://w3id.org/xapi/dod-isd/verbs/answered";
208 }
209 if ((bool) $row->completed) {
210 $sarr[] = "http://adlnet.gov/expapi/verbs/completed";
211 $sarr[] = "https://w3id.org/xapi/dod-isd/verbs/completed";
212 }
213 if ((bool) $row->failed) {
214 $sarr[] = "http://adlnet.gov/expapi/verbs/failed";
215 }
216 if ((bool) $row->initialized) {
217 $sarr[] = "http://adlnet.gov/expapi/verbs/initialized";
218 $sarr[] = "https://w3id.org/xapi/dod-isd/verbs/initialized";
219 }
220 if ((bool) $row->passed) {
221 $sarr[] = "http://adlnet.gov/expapi/verbs/passed";
222 }
223 if ((bool) $row->progressed) {
224 $sarr[] = "http://adlnet.gov/expapi/verbs/progressed";
225 }
226 if ((bool) $row->satisfied) {
227 $sarr[] = "https://w3id.org/xapi/adl/verbs/satisfied";
228 }
229 if ((bool) $row->c_terminated) {
230 $sarr[] = "http://adlnet.gov/expapi/verbs/terminated";
231 }
232 if (count($sarr) > 0) {
233 $this->specificAllowedStatements = $sarr;
234 $this->log()->debug($this->msg('getSpecificAllowedStatements: ' . var_export($this->specificAllowedStatements, true)));
235 }
236 }
237 if ((bool) $row->hide_data) {
238 $rarr = array();
239 if ((bool) $row->c_timestamp) {
240 $rarr['timestamp'] = '1970-01-01T00:00:00.000Z';
241 }
242 if ((bool) $row->duration) {
243 $rarr['result.duration'] = 'PT00.000S';
244 }
245 if (count($rarr) > 0) {
246 $this->replacedValues = $rarr;
247 $this->log()->debug($this->msg('getReplacedValues: ' . var_export($this->replacedValues, true)));
248 }
249 }
250 if ((bool) $row->no_substatements) {
251 $this->blockSubStatements = true;
252 $this->log()->debug($this->msg('getBlockSubStatements: ' . $this->blockSubStatements));
253 }
254 $lrs->setPrivacyIdent((int) $row->privacy_ident);
255 }
256 return $lrs;
257 }
258 }
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
An exception for terminatinating execution or to throw for unit testing.
__construct($client, $token, $plugin=false)
getLrsTypeAndMoreByToken()
hybrid function, maybe two distinct functions would be better?
static saveProxySuccess($objId, $usrId, $privacyIdent)
if($_SERVER['argc']< 4) $client
Definition: cron.php:12
exit
Definition: login.php:29
static http()
Fetches the global http state from ILIAS.
$query
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
$log
Definition: result.php:15
foreach($_POST as $key=> $value) $res
$token
Definition: xapitoken.php:52
$objId
Definition: xapitoken.php:39