ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilSessionReminderCheck.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
27 
28 readonly class ilSessionReminderCheck
29 {
30  public function __construct(
31  private GlobalHttpState $http,
32  private Refinery $refinery,
33  private ilLanguage $lng,
34  private ilDBInterface $db,
35  private ilIniFile $client_ini,
36  private ilLogger $logger,
37  private ClockInterface $clock,
38  private ilSetting $settings
39  ) {
40  }
41 
42  public function handle(): ResponseInterface
43  {
44  $hash = ilUtil::stripSlashes(
45  $this->http->wrapper()->post()->retrieve(
46  'hash',
47  $this->refinery->kindlyTo()->string()
48  )
49  );
50 
51  $this->logger->debug('Session reminder call for session id hash: ' . $hash);
52 
53  // disable session writing and extension of expiration time
55 
56  $response = ['remind' => false];
57 
58  $concat = $this->db->concat(
59  [
60  ['usess.session_id'],
61  ['usess.user_id'],
62  ['od.create_date']
63  ]
64  );
65  $res = $this->db->queryF(
66  'SELECT usess.expires, usess.user_id, usess.data ' .
67  'FROM usr_session usess ' .
68  'INNER JOIN object_data od ON od.obj_id = usess.user_id ' .
69  "WHERE SHA2($concat, 256) = %s",
71  [$hash]
72  );
73 
74  $num = $this->db->numRows($res);
75 
76  if ($num === 0) {
77  $response['message'] = 'ILIAS could not determine the session data.';
78  return $this->toJsonResponse($response);
79  }
80 
81  if ($num > 1) {
82  $response['message'] = 'The determined session data is not unique.';
83  return $this->toJsonResponse($response);
84  }
85 
86  $data = $this->db->fetchAssoc($res);
87  if (!$this->isAuthenticatedUsrSession($data)) {
88  $response['message'] = 'ILIAS could not fetch the session data or the corresponding user is no more authenticated.';
89  return $this->toJsonResponse($response);
90  }
91 
92  $expiration_time = $data['expires'];
93  if ($expiration_time === null) {
94  $response['message'] = 'ILIAS could not determine the expiration time from the session data.';
95  return $this->toJsonResponse($response);
96  }
97  $expiration_time = (int) $data['expires'];
98 
99  if ($this->isSessionAlreadyExpired($expiration_time)) {
100  $response['message'] = 'The session is already expired. The client should have received a remind command before.';
101  return $this->toJsonResponse($response);
102  }
103 
105  $ilUser = ilObjectFactory::getInstanceByObjId((int) $data['user_id'], false);
106  if (!($ilUser instanceof ilObjUser)) {
107  $response['message'] = 'ILIAS could not fetch the session data or the corresponding user is no more authenticated.';
108  return $this->toJsonResponse($response);
109  }
110 
111  $session_reminder = new ilSessionReminder(
112  $ilUser,
113  $this->clock,
114  $this->settings
115  );
116  $reminder_time = $expiration_time - ($session_reminder->getEffectiveLeadTime() * 60);
117  if ($reminder_time > $this->clock->now()->getTimestamp()) {
118  // session will expire in <lead_time> minutes
119  $response['message'] = 'Lead time not reached, yet. Current time: ' .
120  date('Y-m-d H:i:s') . ', Reminder time: ' . date('Y-m-d H:i:s', $reminder_time);
121  return $this->toJsonResponse($response);
122  }
123 
124  $dateTime = new ilDateTime($expiration_time, IL_CAL_UNIX);
125  switch ($ilUser->getTimeFormat()) {
127  $formatted_expiration_time = $dateTime->get(IL_CAL_FKT_DATE, 'g:ia', $ilUser->getTimeZone());
128  break;
129 
131  default:
132  $formatted_expiration_time = $dateTime->get(IL_CAL_FKT_DATE, 'H:i', $ilUser->getTimeZone());
133  break;
134  }
135 
136  $response = [
137  'extend_url' => './ilias.php?baseClass=' . ilDashboardGUI::class,
138  'txt' => str_replace(
139  "\\n",
140  '%0A',
141  sprintf(
142  $this->lng->txt('session_reminder_alert'),
143  ilDatePresentation::secondsToString($expiration_time - $this->clock->now()->getTimestamp()),
144  $formatted_expiration_time,
145  $this->client_ini->readVariable('client', 'name') . ' | ' . ilUtil::_getHttpPath()
146  )
147  ),
148  'remind' => true
149  ];
150 
151  return $this->toJsonResponse($response);
152  }
153 
158  private function toJsonResponse($data): ResponseInterface
159  {
160  return $this->http->response()
161  ->withHeader(ResponseHeader::CONTENT_TYPE, 'application/json')
162  ->withBody(Streams::ofString(json_encode($data, JSON_THROW_ON_ERROR)));
163  }
164 
165  private function isSessionAlreadyExpired(int $expirationTime): bool
166  {
167  return $expirationTime < $this->clock->now()->getTimestamp();
168  }
169 
170  private function isAuthenticatedUsrSession(?array $data): bool
171  {
172  return (
173  is_array($data) &&
174  isset($data['user_id']) &&
175  (int) $data['user_id'] > 0 &&
176  (int) $data['user_id'] !== ANONYMOUS_USER_ID
177  );
178  }
179 }
$res
Definition: ltiservices.php:66
static enableWebAccessWithoutSession(bool $enable_web_access_without_session)
const ANONYMOUS_USER_ID
Definition: constants.php:27
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
isSessionAlreadyExpired(int $expirationTime)
$response
Definition: xapitoken.php:93
$http
Definition: deliver.php:30
const IL_CAL_UNIX
static secondsToString(int $seconds, bool $force_with_seconds=false, ?ilLanguage $a_lng=null)
converts seconds to string: Long: 7 days 4 hour(s) ...
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
static http()
Fetches the global http state from ILIAS.
__construct(private GlobalHttpState $http, private Refinery $refinery, private ilLanguage $lng, private ilDBInterface $db, private ilIniFile $client_ini, private ilLogger $logger, private ClockInterface $clock, private ilSetting $settings)
const IL_CAL_FKT_DATE
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
static _getHttpPath()
global $lng
Definition: privfeed.php:31