ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
XapiProxy.php
Go to the documentation of this file.
1 <?php
2  namespace XapiProxy;
3 
4  require_once __DIR__.'/XapiProxyPolyFill.php';
5 
6  class XapiProxy extends XapiProxyPolyFill {
7 
10 
11  public function __construct($client, $token, $plugin=false) {
13  $this->log()->debug($this->msg('proxy initialized'));
14  }
15 
16  public function setRequestParams($request) {
17  preg_match(self::PARTS_REG, $request->getUri(), $this->cmdParts);
18  }
19 
20  public function token() {
21  return $this->token;
22  }
23 
24  public function client() {
25  return $this->client;
26  }
27 
28  public function lrsType() {
29  return $this->lrsType;
30  }
31 
32  public function replacedValues() {
33  return $this->replacedValues;
34  }
35 
36  public function specificAllowedStatements() {
37  return $this->specificAllowedStatements;
38  }
39 
40  public function blockSubStatements() {
41  return $this->blockSubStatements;
42  }
43 
44  public function cmdParts() {
45  return $this->cmdParts;
46  }
47 
48  public function method() {
49  return $this->method;
50  }
51 
52  public function getDefaultLrsEndpoint() {
53  return $this->defaultLrsEndpoint;
54  }
55 
56  public function getDefaultLrsKey() {
57  return $this->defaultLrsKey;
58  }
59 
60  public function getDefaultLrsSecret() {
61  return $this->defaultLrsSecret;
62  }
63 
64  public function getFallbackLrsEndpoint() {
65  return $this->fallbackLrsEndpoint;
66  }
67 
68  public function getFallbackLrsKey() {
69  return $this->fallbackLrsKey;
70  }
71 
72  public function getFallbackLrsSecret() {
73  return $this->fallbackLrsSecret;
74  }
75 
76  public function setXapiProxyRequest($xapiProxyRequest) {
77  $this->xapiProxyRequest = $xapiProxyRequest;
78  }
79 
80  public function getXapiProxyRequest() {
81  return $this->xapiProxyRequest;
82  }
83 
84  public function setXapiProxyResponse($xapiProxyResponse) {
85  $this->xapiProxyResponse = $xapiProxyResponse;
86  }
87 
88  public function getXapiProxyResponse() {
89  return $this->xapiProxyResponse;
90  }
91 
92  public function processStatements($request, $body) {
93  // everything is allowed
94  if (!is_array($this->specificAllowedStatements) && !$this->blockSubStatements) {
95  $this->log()->debug($this->msg("all statement are allowed"));
96  return NULL;
97  }
98  $obj = json_decode($body, false);
99  // single statement object
100  if (is_object($obj) && isset($obj->verb)) {
101  $this->log()->debug($this->msg("json is object and statement"));
102  $isSubStatement = $this->isSubStatementCheck($obj);
103  $verb = $obj->verb->id;
104  if ($this->blockSubStatements && $isSubStatement) {
105  $this->log()->debug($this->msg("sub-statement is NOT allowed, fake response - " . $verb));
106  $this->xapiProxyResponse->fakeResponseBlocked(NULL);
107  }
108  // $specificAllowedStatements
109  if (!is_array($this->specificAllowedStatements)) {
110  return NULL;
111  }
112  if (in_array($verb,$this->specificAllowedStatements)) {
113  $this->log()->debug($this->msg("statement is allowed, do nothing - " . $verb));
114  return NULL;
115  }
116  else {
117  $this->log()->debug($this->msg("statement is NOT allowed, fake response - " . $verb));
118  $this->xapiProxyResponse->fakeResponseBlocked(NULL);
119  }
120  }
121  // array of statement objects
122  if (is_array($obj) && count($obj) > 0 && isset($obj[0]->verb)) {
123  $this->log()->debug($this->msg("json is array of statements"));
124  $ret = array();
125  $up = array();
126  for ($i=0; $i<count($obj); $i++) {
127  array_push($ret,$obj[$i]->id); // push every statementid for fakePostResponse
128  $isSubStatement = $this->isSubStatementCheck($obj[$i]);
129  $verb = $obj[$i]->verb->id;
130  if ($this->blockSubStatements && $isSubStatement) {
131  $this->log()->debug($this->msg("sub-statement is NOT allowed - " .$verb));
132  }
133  else {
134  if (!is_array($this->specificAllowedStatements) || (is_array($this->specificAllowedStatements) && in_array($verb,$this->specificAllowedStatements))) {
135  $this->log()->debug($this->msg("statement is allowed - " . $verb));
136  array_push($up,$obj[$i]);
137  }
138  }
139  }
140  if (count($up) === 0) { // nothing allowed
141  $this->log()->debug($this->msg("no allowed statements in array - fake response..."));
142  $this->xapiProxyResponse->fakeResponseBlocked($ret);
143  }
144  elseif (count($up) !== count($ret)) { // mixed request with allowed and not allowed statements
145  $this->log()->debug($this->msg("mixed with allowed and unallowed statements"));
146  return array($up,$ret);
147  }
148  else {
149  // just return nothing
150  return NULL;
151  }
152  }
153  return NULL;
154  }
155 
156  public function modifyBody($body)
157  {
158  $obj = json_decode($body, false);
159 
160  if (json_last_error() != JSON_ERROR_NONE) {
161  // JSON is not valid
162  $this->log()->error($this->msg(json_last_error_msg()));
163  return $body;
164  }
165 
166  // $log->debug(json_encode($obj, JSON_PRETTY_PRINT)); // only in DEBUG mode for better performance
167  if (is_object($obj)) {
168  if (is_array($this->replacedValues)) {
169  foreach ($this->replacedValues as $key => $value) {
170  $this->setValue($obj,$key,$value);
171  }
172  }
173  $this->handleStatementEvaluation($obj); // ToDo
174  }
175 
176  if (is_array($obj)) {
177  for ($i = 0; $i < count($obj); $i++) {
178  if (is_array($this->replacedValues)) {
179  foreach ($this->replacedValues as $key => $value) {
180  $this->setValue($obj[$i],$key,$value);
181  }
182  }
183  $this->handleStatementEvaluation($obj[$i]); // ToDo
184  }
185  }
186  return json_encode($obj);
187  }
188 
189  private function handleStatementEvaluation($xapiStatement)
190  {
191  global $DIC;
192  if ($this->plugin) {
193  require_once __DIR__.'/../class.ilObjXapiCmi5.php';
194  // ToDo: handle terminate -> delete session
195  $this->setStatus($xapiStatement);
196  }
197  else {
198  /* @var $object */
199  $object = \ilObjectFactory::getInstanceByObjId($this->authToken->getObjId());
200  if( (string)$object->getLaunchMode() === (string)\ilObjCmiXapi::LAUNCH_MODE_NORMAL ) {
201  // ToDo: check function hasContextActivitiesParentNotEqualToObject!
202  $statementEvaluation = new \ilXapiStatementEvaluation($this->log(), $object);
203  $statementEvaluation->evaluateStatement($xapiStatement, $this->authToken->getUsrId());
204 
206  $this->authToken->getObjId(),
207  $this->authToken->getUsrId()
208  );
209  }
210  if ($xapiStatement->verb->id == self::TERMINATED_VERB) {
211  // ToDo : only cmi5 or also xapi? authToken object still used after that?
212  $this->authToken->delete();
213  }
214  }
215  }
216 
217  private function setValue(&$obj, $path, $value) {
218  $path_components = explode('.', $path);
219  if (count($path_components) == 1) {
220  if (property_exists($obj,$path_components[0])) {
221  $obj->{$path_components[0]} = $value;
222  }
223  }
224  else {
225  if (property_exists($obj, $path_components[0])) {
226  $this->setValue($obj->{array_shift($path_components)}, implode('.', $path_components), $value);
227  }
228  }
229  }
230 
231  private function setStatus($obj) {
232  if (isset($obj->verb) && isset($obj->actor) && isset($obj->object)) {
233  $verb = $obj->verb->id;
234  $score = 'NOT_SET';
235  if (array_key_exists($verb, $this->sniffVerbs)) {
236  // check context
237  if ($this->isSubStatementCheck($obj)) {
238  $this->log()->debug($this->msg("statement is sub-statement, ignore status verb " . $verb));
239  return;
240  }
241  if (isset($obj->result) && isset($obj->result->score) && isset($obj->result->score->scaled)) {
242  $score = $obj->result->score->scaled;
243  }
244  $this->log()->debug($this->msg("handleLPStatus: " . $this->sniffVerbs[$verb] . " : " . $score));
245  \ilObjXapiCmi5::handleLPStatusFromProxy($this->client, $this->token, $this->sniffVerbs[$verb], $score);//UK check
246  }
247  }
248  }
249 
250  private function isSubStatementCheck($obj) {
251  $object = \ilObjectFactory::getInstanceByObjId($this->authToken->getObjId()); // get ActivityId in Constructor for better performance, is also used in handleEvaluationStatement
252  $objActivityId = $object->getActivityId();
253  $statementActivityId = $obj->object->id;
254  if ($statementActivityId != $objActivityId) {
255  $this->log()->debug($this->msg("statement object id " . $statementActivityId . " != activityId " . $objActivityId));
256  $this->log()->debug($this->msg("is Substatement"));
257  return true;
258  }
259  else {
260  $this->log()->debug($this->msg("is not Substatement"));
261  return false;
262  }
263  }
264  }
265 ?>
processStatements($request, $body)
Definition: XapiProxy.php:92
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
setRequestParams($request)
Definition: XapiProxy.php:16
if($_SERVER['argc']< 4) $client
Definition: cron.php:12
setXapiProxyRequest($xapiProxyRequest)
Definition: XapiProxy.php:76
$token
Definition: xapitoken.php:57
__construct($client, $token, $plugin=false)
Definition: XapiProxy.php:11
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
setXapiProxyResponse($xapiProxyResponse)
Definition: XapiProxy.php:84
__construct(Container $dic, ilPlugin $plugin)
$ret
Definition: parser.php:6
$DIC
Definition: xapitoken.php:46
setValue(&$obj, $path, $value)
Definition: XapiProxy.php:217
handleStatementEvaluation($xapiStatement)
Definition: XapiProxy.php:189
$i
Definition: metadata.php:24