ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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  }
exit
Definition: login.php:29
if($_SERVER['argc']< 4) $client
Definition: cron.php:12
$objId
Definition: xapitoken.php:39
static http()
Fetches the global http state from ILIAS.
foreach($_POST as $key=> $value) $res
$log
Definition: result.php:15
$token
Definition: xapitoken.php:52
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
getLrsTypeAndMoreByToken()
hybrid function, maybe two distinct functions would be better?
$query
__construct($client, $token, $plugin=false)
static saveProxySuccess($objId, $usrId, $privacyIdent)