ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilLSStateDB.php
Go to the documentation of this file.
1 <?php
2 
3 declare(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 }
entryExistsFor(int $lso_ref_id, int $usr_id)
getCurrentItemsFor(int $lso_ref_id, array $usr_ids=[])
deleteFor(int $lso_ref_id, array $usr_ids=[])
$result
serializeStates(array $states)
Class BaseForm.
PHP_EOL
Definition: complexTest.php:5
insert(int $lso_ref_id, int $usr_id)
update($table_name, $values, $where)
getFirstAccessFor(int $lso_ref_id, array $usr_ids=[])
deleteForItem(int $lso_ref_id, int $item_ref_id)
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...
update(ilDBInterface $db, int $lso_ref_id, int $usr_id, int $current_item, string $serialized)
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$values
getStatesFor(int $lso_ref_id, array $usr_ids=[])
Persistence for View-States.
$query
$row
buildStates(string $serialized)
__construct(ilDBInterface $db)
$ret
Definition: parser.php:6
select(int $lso_ref_id, array $usr_ids=[])
$key
Definition: croninfo.php:18
getLastAccessFor(int $lso_ref_id, array $usr_ids=[])
$data
Definition: bench.php:6