Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.06% covered (success)
97.06%
33 / 34
87.50% covered (warning)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
SessionHandler
97.06% covered (success)
97.06%
33 / 34
87.50% covered (warning)
87.50%
7 / 8
19
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLastInstance
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setHttpHandler
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 open
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 close
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 read
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
9.02
 write
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 destroy
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 gc
n/a
0 / 0
n/a
0 / 0
1
1<?php
2
3namespace BO\Zmsclient;
4
5use BO\Zmsentities\Session;
6
7class SessionHandler implements \SessionHandlerInterface
8{
9    public $sessionName;
10
11    /**
12     * Adds a parameter "sync" on reading the session from the API
13     * Use a value of 1 to enable synchronous reads
14     * if a former session write happened during a redirect
15     */
16    public static $useSyncFlag = 0;
17
18    protected static $lastInstance = null;
19
20    /**
21     * @var \BO\Zmsclient\Http $http
22     *
23     */
24    protected $http = null;
25
26
27    public function __construct(Http $http)
28    {
29        $this->setHttpHandler($http);
30        static::$lastInstance = $this;
31    }
32
33    /** @psalm-api */
34    public static function getLastInstance(): ?self
35    {
36        return static::$lastInstance;
37    }
38
39    public function setHttpHandler(Http $http): void
40    {
41        $this->http = $http;
42    }
43
44    /**
45     * @SuppressWarnings(UnusedFormalParameter)
46     */
47    #[\Override]
48    public function open(string $path, string $name): bool
49    {
50        $this->sessionName = $name;
51        return true;
52    }
53
54    /** @psalm-api Required by SessionHandlerInterface and used by PHP session shutdown. */
55    #[\Override]
56    public function close(): bool
57    {
58        return true;
59    }
60
61    #[\Override]
62    public function read(string $id, array $params = []): string
63    {
64        $hashedSessionId = hash('sha256', $id);
65        $params['sync'] = static::$useSyncFlag;
66        try {
67            $session = $this->http->readGetResult(
68                '/session/' . $this->sessionName . '/' . $hashedSessionId . '/',
69                $params
70            )
71            ->getEntity();
72        } catch (Exception\ApiFailed $exception) {
73            throw $exception;
74        } catch (Exception $exception) {
75            if ($exception->getCode() == 404) {
76                $session = false;
77            } else {
78                throw $exception;
79            }
80        }
81        if (isset($params['oidc']) && 1 == $params['oidc'] && $session) {
82            $session = $session->withOidcDataOnly();
83        }
84        return ($session && isset($session['content'])) ? serialize($session->getContent()) : '';
85    }
86
87    #[\Override]
88    public function write(string $id, string $data, array $params = []): bool
89    {
90        $hashedSessionId = hash('sha256', $id);
91        $entity = new Session();
92        $entity->id = $hashedSessionId;
93        $entity->name = $this->sessionName;
94        $entity->content = unserialize($data);
95
96        $session = $this->http->readPostResult('/session/', $entity, $params)
97            ->getEntity();
98
99        return (null !== $session) ? true : false;
100    }
101
102    #[\Override]
103    public function destroy(string $id): bool
104    {
105        $hashedSessionId = hash('sha256', $id);
106        $result = $this->http->readDeleteResult('/session/' . $this->sessionName . '/' . $hashedSessionId . '/');
107        return ($result) ? true : false;
108    }
109
110    /**
111     * @SuppressWarnings(UnusedFormalParameter)
112     * @SuppressWarnings(ShortMethodName)
113     * @codeCoverageIgnore
114     * @psalm-api
115     */
116    #[\Override]
117    public function gc(int $max_lifetime): int|false
118    {
119        /*
120         * $compareTs = time() - $max_lifetime;
121         * $query = '
122         * DELETE FROM
123         * sessiondata
124         * WHERE
125         * UNIX_TIMESTAMP(`ts`) < ? AND
126         * sessionname=?
127         * ';
128         * $statement = $this->getWriter()->prepare($query);
129         * return $statement->execute(array(
130         * $compareTs,
131         * $this->sessionName
132         * ));
133         */
134        return 1;
135    }
136}