ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilBadgeAssignment.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
13{
14 protected $badge_id; // [int]
15 protected $user_id; // [int]
16 protected $tstamp; // [timestamp]
17 protected $awarded_by; // [int]
18 protected $pos; // [int]
19 protected $stored; // [bool]
20
21 public function __construct($a_badge_id = null, $a_user_id = null)
22 {
23 if($a_badge_id &&
24 $a_user_id)
25 {
26 $this->setBadgeId($a_badge_id);
27 $this->setUserId($a_user_id);
28
29 $this->read($a_badge_id, $a_user_id);
30 }
31 }
32
33 public static function getInstancesByUserId($a_user_id)
34 {
35 global $ilDB;
36
37 $res = array();
38
39 $set = $ilDB->query("SELECT * FROM badge_user_badge".
40 " WHERE user_id = ".$ilDB->quote($a_user_id, "integer").
41 " ORDER BY pos");
42 while($row = $ilDB->fetchAssoc($set))
43 {
44 $obj = new self();
45 $obj->importDBRow($row);
46 $res[] = $obj;
47 }
48
49 return $res;
50 }
51
52 public static function getInstancesByBadgeId($a_badge_id)
53 {
54 global $ilDB;
55
56 $res = array();
57
58 $set = $ilDB->query("SELECT * FROM badge_user_badge".
59 " WHERE badge_id = ".$ilDB->quote($a_badge_id, "integer"));
60 while($row = $ilDB->fetchAssoc($set))
61 {
62 $obj = new self();
63 $obj->importDBRow($row);
64 $res[] = $obj;
65 }
66
67 return $res;
68 }
69
70 public static function getInstancesByParentId($a_parent_obj_id)
71 {
72 global $ilDB;
73
74 $res = array();
75
76 $badge_ids = array();
77 foreach(ilBadge::getInstancesByParentId($a_parent_obj_id) as $badge)
78 {
79 $badge_ids[] = $badge->getId();
80 }
81 if(sizeof($badge_ids))
82 {
83 $set = $ilDB->query("SELECT * FROM badge_user_badge".
84 " WHERE ".$ilDB->in("badge_id", $badge_ids, "", "integer"));
85 while($row = $ilDB->fetchAssoc($set))
86 {
87 $obj = new self();
88 $obj->importDBRow($row);
89 $res[] = $obj;
90 }
91 }
92
93 return $res;
94 }
95
96 public static function getAssignedUsers($a_badge_id)
97 {
98 $res = array();
99
100 foreach(self::getInstancesByBadgeId($a_badge_id) as $ass)
101 {
102 $res[] = $ass->getUserId();
103 }
104
105 return $res;
106 }
107
108 public static function exists($a_badge_id, $a_user_id)
109 {
110 $obj = new self($a_badge_id, $a_user_id);
111 return $obj->stored;
112 }
113
114
115 //
116 // setter/getter
117 //
118
119 protected function setBadgeId($a_value)
120 {
121 $this->badge_id = (int)$a_value;
122 }
123
124 public function getBadgeId()
125 {
126 return $this->badge_id;
127 }
128
129 protected function setUserId($a_value)
130 {
131 $this->user_id = (int)$a_value;
132 }
133
134 public function getUserId()
135 {
136 return $this->user_id;
137 }
138
139 protected function setTimestamp($a_value)
140 {
141 $this->tstamp = (int)$a_value;
142 }
143
144 public function getTimestamp()
145 {
146 return $this->tstamp;
147 }
148
149 public function setAwardedBy($a_id)
150 {
151 $this->awarded_by = (int)$a_id;
152 }
153
154 public function getAwardedBy()
155 {
156 return $this->awarded_by;
157 }
158
159 public function setPosition($a_value)
160 {
161 if($a_value !== null)
162 {
163 $a_value = (int)$a_value;
164 }
165 $this->pos = $a_value;
166 }
167
168 public function getPosition()
169 {
170 return $this->pos;
171 }
172
173
174 //
175 // crud
176 //
177
178 protected function importDBRow(array $a_row)
179 {
180 $this->stored = true;
181 $this->setBadgeId($a_row["badge_id"]);
182 $this->setUserId($a_row["user_id"]);
183 $this->setTimestamp($a_row["tstamp"]);
184 $this->setAwardedBy($a_row["awarded_by"]);
185 $this->setPosition($a_row["pos"]);
186 }
187
188 protected function read($a_badge_id, $a_user_id)
189 {
190 global $ilDB;
191
192 $set = $ilDB->query("SELECT * FROM badge_user_badge".
193 " WHERE badge_id = ".$ilDB->quote($a_badge_id, "integer").
194 " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
195 $row = $ilDB->fetchAssoc($set);
196 if($row["user_id"])
197 {
198 $this->importDBRow($row);
199 }
200 }
201
202 protected function getPropertiesForStorage()
203 {
204 return array(
205 "tstamp" => array("integer", (bool)$this->stored ? $this->getTimestamp() : time()),
206 "awarded_by" => array("integer", $this->getAwardedBy()),
207 "pos" => array("integer", $this->getPosition())
208 );
209 }
210
211 public function store()
212 {
213 global $ilDB;
214
215 if(!$this->getBadgeId() ||
216 !$this->getUserId())
217 {
218 return;
219 }
220
221 $keys = array(
222 "badge_id" => array("integer", $this->getBadgeId()),
223 "user_id" => array("integer", $this->getUserId())
224 );
225 $fields = $this->getPropertiesForStorage();
226
227 if(!(bool)$this->stored)
228 {
229 $ilDB->insert("badge_user_badge", $fields + $keys);
230 }
231 else
232 {
233 $ilDB->update("badge_user_badge", $fields, $keys);
234 }
235 }
236
237 public function delete()
238 {
239 global $ilDB;
240
241 if(!$this->getBadgeId() ||
242 !$this->getUserId())
243 {
244 return;
245 }
246
247 $this->deleteStaticFiles();
248
249 $ilDB->manipulate("DELETE FROM badge_user_badge".
250 " WHERE badge_id = ".$ilDB->quote($this->getBadgeId(), "integer").
251 " AND user_id = ".$ilDB->quote($this->getUserId(), "integer"));
252 }
253
254 public static function deleteByUserId($a_user_id)
255 {
256 foreach(self::getInstancesByUserId($a_user_id) as $ass)
257 {
258 $ass->delete();
259 }
260 }
261
262 public static function deleteByBadgeId($a_badge_id)
263 {
264 foreach(self::getInstancesByBadgeId($a_badge_id) as $ass)
265 {
266 $ass->delete();
267 }
268 }
269
270 public static function deleteByParentId($a_parent_obj_id)
271 {
272 foreach(self::getInstancesByParentId($a_parent_obj_id) as $ass)
273 {
274 $ass->delete();
275 }
276 }
277
278 public static function updatePositions($a_user_id, array $a_positions)
279 {
280 $existing = array();
281 include_once "Services/Badge/classes/class.ilBadge.php";
282 foreach(self::getInstancesByUserId($a_user_id) as $ass)
283 {
284 $badge = new ilBadge($ass->getBadgeId());
285 $existing[$badge->getId()] = array($badge->getTitle(), $ass);
286 }
287
288 $new_pos = 0;
289 foreach($a_positions as $title)
290 {
291 foreach($existing as $id => $item)
292 {
293 if($title == $item[0])
294 {
295 $item[1]->setPosition(++$new_pos);
296 $item[1]->store();
297 unset($existing[$id]);
298 }
299 }
300 }
301 }
302
303
304 //
305 // PUBLISHING
306 //
307
308 protected function prepareJson($a_url)
309 {
310 $verify = new stdClass();
311 $verify->type = "hosted";
312 $verify->url = $a_url;
313
314 $recipient = new stdClass();
315 $recipient->type = "email";
316 $recipient->hashed = true;
317 $recipient->salt = ilBadgeHandler::getInstance()->getObiSalt();
318
319 // https://github.com/mozilla/openbadges-backpack/wiki/How-to-hash-&-salt-in-various-languages.
320 include_once "Services/Badge/classes/class.ilBadgeProfileGUI.php";
321 $user = new ilObjUser($this->getUserId());
322 $mail = $user->getPref(ilBadgeProfileGUI::BACKPACK_EMAIL);
323 if(!$mail)
324 {
325 $mail = $user->getEmail();
326 }
327 $recipient->identity = 'sha256$'.hash('sha256', $mail.$recipient->salt);
328
329 // spec: should be locally unique
330 $unique_id = md5($this->getBadgeId()."-".$this->getUserId());
331
332 $json = new stdClass();
333 $json->{"@context"} = "https://w3id.org/openbadges/v1";
334 $json->type = "Assertion";
335 $json->id = $a_url;
336 $json->uid = $unique_id;
337 $json->recipient = $recipient;
338
339 include_once "Services/Badge/classes/class.ilBadge.php";
340 $badge = new ilBadge($this->getBadgeId());
341 $badge_url = $badge->getStaticUrl();
342
343 // created baked image
344 $baked_image = $this->getImagePath($badge);
345 if($this->bakeImage($baked_image, $badge->getImagePath(), $a_url))
346 {
347 // path to url
348 $parts = explode("/", $a_url);
349 array_pop($parts);
350 $parts[] = basename($baked_image);
351 $json->image = implode("/", $parts);
352 }
353
354 $json->issuedOn = $this->getTimestamp();
355 $json->badge = $badge_url;
356 $json->verify = $verify;
357
358 return $json;
359 }
360
361 public function getImagePath(ilBadge $a_badge)
362 {
363 $json_path = ilBadgeHandler::getInstance()->getInstancePath($this);
364 $baked_path = dirname($json_path);
365 $baked_file = array_shift(explode(".", basename($json_path)));
366
367 // get correct suffix from badge image
368 $suffix = strtolower(array_pop(explode(".", basename($a_badge->getImagePath()))));
369 return $baked_path."/".$baked_file.".".$suffix;
370 }
371
372 protected function bakeImage($a_baked_image_path, $a_badge_image_path, $a_assertion_url)
373 {
374 $suffix = strtolower(array_pop(explode(".", basename($a_badge_image_path))));
375 if($suffix == "png")
376 {
377 // using chamilo baker lib
378 include_once "Services/Badge/lib/baker.lib.php";
379 $png = new PNGImageBaker(file_get_contents($a_badge_image_path));
380
381 // add payload
382 if($png->checkChunks("tEXt", "openbadges"))
383 {
384 $baked = $png->addChunk("tEXt", "openbadges", $a_assertion_url);
385 }
386
387 // create baked file
388 if(!file_exists($a_baked_image_path))
389 {
390 file_put_contents($a_baked_image_path, $baked);
391 }
392
393 // verify file
394 $verify = $png->extractBadgeInfo(file_get_contents($a_baked_image_path));
395 if(is_array($verify))
396 {
397 return true;
398 }
399 }
400 else if($suffix == "svg")
401 {
402 // :TODO: not really sure if this is correct
403 $svg = simplexml_load_file($a_badge_image_path);
404 $ass = $svg->addChild("openbadges:assertion", "", "http://openbadges.org");
405 $ass->addAttribute("verify", $a_assertion_url);
406 $baked = $svg->asXML();
407
408 // create baked file
409 if(!file_exists($a_baked_image_path))
410 {
411 file_put_contents($a_baked_image_path, $baked);
412 }
413
414 return true;
415 }
416
417 return false;
418 }
419
420 public function getStaticUrl()
421 {
422 include_once("./Services/Badge/classes/class.ilBadgeHandler.php");
423 $path = ilBadgeHandler::getInstance()->getInstancePath($this);
424
425 $url = ILIAS_HTTP_PATH.substr($path, 1);
426
427 if(!file_exists($path))
428 {
429 $json = json_encode($this->prepareJson($url));
430 file_put_contents($path, $json);
431 }
432
433 return $url;
434 }
435
436 public function deleteStaticFiles()
437 {
438 // remove instance files
439 include_once("./Services/Badge/classes/class.ilBadgeHandler.php");
440 $path = ilBadgeHandler::getInstance()->getInstancePath($this);
441 $path = str_replace(".json", ".*", $path);
442 array_map("unlink", glob($path));
443 }
444
445 public static function clearBadgeCache($a_user_id)
446 {
447 foreach(self::getInstancesByUserId($a_user_id) as $ass)
448 {
449 $ass->deleteStaticFiles();
450 }
451 }
452}
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
Php library to Bake the PNG Images.
Definition: baker.lib.php:8
static getInstancesByUserId($a_user_id)
bakeImage($a_baked_image_path, $a_badge_image_path, $a_assertion_url)
static getAssignedUsers($a_badge_id)
static clearBadgeCache($a_user_id)
static deleteByBadgeId($a_badge_id)
static getInstancesByBadgeId($a_badge_id)
read($a_badge_id, $a_user_id)
static deleteByUserId($a_user_id)
__construct($a_badge_id=null, $a_user_id=null)
getImagePath(ilBadge $a_badge)
static updatePositions($a_user_id, array $a_positions)
static exists($a_badge_id, $a_user_id)
static getInstancesByParentId($a_parent_obj_id)
static deleteByParentId($a_parent_obj_id)
static getInstance()
Constructor.
static getInstancesByParentId($a_parent_id, array $a_filter=null)
getImagePath($a_full_path=true)
$url
Definition: shib_logout.php:72
global $ilDB