ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilLSStateDB.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
11{
12 const TABLE_NAME = 'lso_states';
13
14 const CURRENT_ITEM_ID = "current_item";
15 const STATES = "states";
16 const FIRST_ACCESS = "first_access";
17 const LAST_ACCESS = "last_access";
18
22 protected $db;
23
24 public function __construct(ilDBInterface $db)
25 {
26 $this->db = $db;
27 }
28
32 public function getStatesFor(int $lso_ref_id, array $usr_ids = []) : array
33 {
34 $data = $this->select($lso_ref_id, $usr_ids);
35 $ret = [];
36 foreach ($usr_ids as $usr_id) {
37 $ret[$usr_id] = [];
38 if (array_key_exists($usr_id, $data)) {
39 $ret[$usr_id] = $data[$usr_id][self::STATES];
40 }
41 }
42
43 return $ret;
44 }
45
49 public function getCurrentItemsFor(int $lso_ref_id, array $usr_ids = []) : array
50 {
51 $data = $this->select($lso_ref_id, $usr_ids);
52 $ret = [];
53 foreach ($usr_ids as $usr_id) {
54 $ret[$usr_id] = -1;
55 if (array_key_exists($usr_id, $data)) {
56 $ret[$usr_id] = $data[$usr_id][self::CURRENT_ITEM_ID];
57 }
58 }
59
60 return $ret;
61 }
62
63 public function getFirstAccessFor(int $lso_ref_id, array $usr_ids = []) : array
64 {
65 $data = $this->select($lso_ref_id, $usr_ids);
66 $ret = [];
67 foreach ($usr_ids as $usr_id) {
68 $ret[$usr_id] = -1;
69 if (array_key_exists($usr_id, $data)) {
70 $ret[$usr_id] = $data[$usr_id][self::FIRST_ACCESS];
71 }
72 }
73
74 return $ret;
75 }
76
77 public function getLastAccessFor(int $lso_ref_id, array $usr_ids = []) : array
78 {
79 $data = $this->select($lso_ref_id, $usr_ids);
80 $ret = [];
81 foreach ($usr_ids as $usr_id) {
82 $ret[$usr_id] = -1;
83 if (array_key_exists($usr_id, $data)) {
84 $ret[$usr_id] = $data[$usr_id][self::LAST_ACCESS];
85 }
86 }
87
88 return $ret;
89 }
90
95 public function updateState(
96 int $lso_ref_id,
97 int $usr_id,
98 int $ref_id,
99 ILIAS\KioskMode\State $state,
100 int $current_item = null
101 ) {
102 $insert_first = $this->entryExistsFor($lso_ref_id, $usr_id) === false;
103 $states = $this->getStatesFor($lso_ref_id, [$usr_id]);
104 $states = $states[$usr_id];
105 $states[$ref_id] = $state;
106 $serialized = $this->serializeStates($states);
107 if (is_null($current_item)) {
108 $current_item = $ref_id;
109 }
110
111 $ilAtomQuery = $this->db->buildAtomQuery();
112 $ilAtomQuery->addTableLock(static::TABLE_NAME);
113 $ilAtomQuery->addQueryCallable(
114 function (ilDBInterface $db) use ($insert_first, $lso_ref_id, $usr_id, $current_item, $serialized) {
115 if ($insert_first) {
116 $this->insert($lso_ref_id, $usr_id);
117 }
118 $this->update($db, $lso_ref_id, $usr_id, $current_item, $serialized);
119 }
120 );
121
122 $ilAtomQuery->run();
123 }
124
125 protected function entryExistsFor(int $lso_ref_id, int $usr_id) : bool
126 {
127 return count($this->select($lso_ref_id, [$usr_id])) > 0;
128 }
129
130 protected function insert(int $lso_ref_id, int $usr_id)
131 {
132 $first_access = date("d.m.Y H:i:s");
133 $values = array(
134 "lso_ref_id" => array("integer", $lso_ref_id),
135 "usr_id" => array("integer", $usr_id),
136 "first_access" => array("text", $first_access)
137 );
138
139 $this->db->insert(static::TABLE_NAME, $values);
140 }
141
142 protected function update(
144 int $lso_ref_id,
145 int $usr_id,
146 int $current_item,
147 string $serialized
148 ) {
149 $last_access = date("d.m.Y H:i:s");
150 $where = array(
151 "lso_ref_id" => array("integer", $lso_ref_id),
152 "usr_id" => array("integer", $usr_id)
153 );
154 $values = array(
155 "current_item" => array("integer", $current_item),
156 "states" => array("text", $serialized),
157 "last_access" => array("text", $last_access)
158 );
159
160 $db->update(static::TABLE_NAME, $values, $where);
161 }
162
167 public function deleteFor(int $lso_ref_id, array $usr_ids = [])
168 {
169 $query =
170 "DELETE FROM " . static::TABLE_NAME . PHP_EOL
171 . "WHERE lso_ref_id = " . $this->db->quote($lso_ref_id, "integer") . PHP_EOL
172 ;
173
174 if (count($usr_ids) > 0) {
175 $query .= "AND usr_id IN (" . implode(',', $usr_ids) . ")";
176 }
177
178 $this->db->manipulate($query);
179 }
180
181 public function deleteForItem(int $lso_ref_id, int $item_ref_id)
182 {
183 $all_states = $this->select($lso_ref_id);
184 if (count($all_states) === 0) {
185 return;
186 }
187
188 $ilAtomQuery = $this->db->buildAtomQuery();
189 $ilAtomQuery->addTableLock(static::TABLE_NAME);
190 $ilAtomQuery->addQueryCallable(
191
192 function (ilDBInterface $db) use ($lso_ref_id, $all_states, $item_ref_id) {
193 foreach ($all_states as $usr_id => $state_entry) {
194 $current_item = $state_entry['current_item'];
195 $states = $state_entry['states'];
196
197 if ($current_item === $item_ref_id) {
198 $current_item = -1;
199 }
200
201 if (array_key_exists($item_ref_id, $states)) {
202 unset($states[$item_ref_id]);
203 }
204 $serialized = $this->serializeStates($states);
205 $this->update($db, $lso_ref_id, $usr_id, $current_item, $serialized);
206 }
207 }
208 );
209
210 $ilAtomQuery->run();
211 }
212
213
217 protected function buildStates(string $serialized) : array
218 {
219 $states = [];
220 $data = json_decode($serialized, true);
221 foreach ($data as $ref_id => $kvpair) {
222 $states[$ref_id] = new ILIAS\KioskMode\State();
223 if (is_array($kvpair)) {
224 foreach ($kvpair as $key => $value) {
225 $states[$ref_id] = $states[$ref_id]->withValueFor($key, $value);
226 }
227 }
228 }
229
230 return $states;
231 }
232
236 protected function serializeStates(array $states)
237 {
238 $data = [];
239 foreach ($states as $ref_id => $state) {
240 $data[$ref_id] = json_decode($state->serialize());
241 }
242
243 return json_encode($data);
244 }
245
246 protected function select(int $lso_ref_id, array $usr_ids = [])
247 {
248 $query =
249 "SELECT usr_id, current_item, states, first_access, last_access" . PHP_EOL
250 . "FROM " . static::TABLE_NAME . PHP_EOL
251 . "WHERE lso_ref_id = " . $this->db->quote($lso_ref_id, "integer") . PHP_EOL
252 ;
253
254 if (count($usr_ids) > 0) {
255 $query .= "AND usr_id IN (" . implode(',', $usr_ids) . ")";
256 }
257
258 $result = $this->db->query($query);
259
260 $ret = [];
261 while ($row = $this->db->fetchAssoc($result)) {
262 $ret[$row['usr_id']] = [
263 self::CURRENT_ITEM_ID => (int) $row[self::CURRENT_ITEM_ID],
264 self::STATES => $this->buildStates($row[self::STATES]),
265 self::FIRST_ACCESS => $row[self::FIRST_ACCESS],
266 self::LAST_ACCESS => $row[self::LAST_ACCESS]
267 ];
268 }
269
270 return $ret;
271 }
272}
$result
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
An exception for terminatinating execution or to throw for unit testing.
Keeps the state of a view in a simple stringly type key-value store.
Definition: State.php:10
Persistence for View-States.
serializeStates(array $states)
insert(int $lso_ref_id, int $usr_id)
select(int $lso_ref_id, array $usr_ids=[])
deleteFor(int $lso_ref_id, array $usr_ids=[])
buildStates(string $serialized)
getFirstAccessFor(int $lso_ref_id, array $usr_ids=[])
__construct(ilDBInterface $db)
update(ilDBInterface $db, int $lso_ref_id, int $usr_id, int $current_item, string $serialized)
deleteForItem(int $lso_ref_id, int $item_ref_id)
getCurrentItemsFor(int $lso_ref_id, array $usr_ids=[])
getLastAccessFor(int $lso_ref_id, array $usr_ids=[])
entryExistsFor(int $lso_ref_id, int $usr_id)
getStatesFor(int $lso_ref_id, array $usr_ids=[])
updateState(int $lso_ref_id, int $usr_id, int $ref_id, ILIAS\KioskMode\State $state, int $current_item=null)
update a single State (for the item with ref_id); if $current_item is not set, assume that $ref_id is...
PHP_EOL
Definition: complexTest.php:7
$key
Definition: croninfo.php:18
Interface ilDBInterface.
$row
Class BaseForm.
$ret
Definition: parser.php:6
$query
$values
$data
Definition: bench.php:6