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
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?>
An exception for terminatinating execution or to throw for unit testing.
setXapiProxyRequest($xapiProxyRequest)
Definition: XapiProxy.php:76
handleStatementEvaluation($xapiStatement)
Definition: XapiProxy.php:189
__construct($client, $token, $plugin=false)
Definition: XapiProxy.php:11
setValue(&$obj, $path, $value)
Definition: XapiProxy.php:217
setRequestParams($request)
Definition: XapiProxy.php:16
setXapiProxyResponse($xapiProxyResponse)
Definition: XapiProxy.php:84
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.
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
if($_SERVER['argc']< 4) $client
Definition: cron.php:12
$i
Definition: metadata.php:24
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$ret
Definition: parser.php:6
$token
Definition: xapitoken.php:57
$DIC
Definition: xapitoken.php:46