Completed
Branch 2.x (b1c655)
by Julián
07:53
created

Sessionware::respondWithSessionCookie()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 15
nc 3
nop 1
1
<?php
2
3
/*
4
 * sessionware (https://github.com/juliangut/sessionware).
5
 * PSR7 session management middleware.
6
 *
7
 * @license BSD-3-Clause
8
 * @link https://github.com/juliangut/sessionware
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
namespace Jgut\Middleware\Sessionware;
13
14
use Jgut\Middleware\Sessionware\Manager\Manager;
15
use Psr\Http\Message\ResponseInterface;
16
use Psr\Http\Message\ServerRequestInterface;
17
18
/**
19
 * PHP session handling middleware.
20
 */
21
class Sessionware
22
{
23
    const SESSION_KEY = '__SESSIONWARE_SESSION__';
24
25
    /**
26
     * @var Manager
27
     */
28
    protected $sessionManager;
29
30
    /**
31
     * @var Session
32
     */
33
    protected $session;
34
35
    /**
36
     * Middleware constructor.
37
     *
38
     * @param Manager $sessionManager
39
     */
40
    public function __construct(Manager $sessionManager)
41
    {
42
        $this->sessionManager = $sessionManager;
43
    }
44
45
    /**
46
     * Get session from request.
47
     *
48
     * @param ServerRequestInterface $request
49
     *
50
     * @return Session
51
     */
52
    public static function getSession(ServerRequestInterface $request)
53
    {
54
        return $request->getAttribute(static::SESSION_KEY);
55
    }
56
57
    /**
58
     * Execute the middleware.
59
     *
60
     * @param ServerRequestInterface $request
61
     * @param ResponseInterface      $response
62
     * @param callable               $next
63
     *
64
     * @throws \RuntimeException
65
     *
66
     * @return ResponseInterface
67
     */
68
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
69
    {
70
        $requestCookies = $request->getCookieParams();
71
        $sessionName = $this->sessionManager->getConfiguration()->getName();
72
        if (array_key_exists($sessionName, $requestCookies) && !empty($requestCookies[$sessionName])) {
73
            $this->sessionManager->setSessionId($requestCookies[$sessionName]);
74
        }
75
76
        $this->session = new Session($this->sessionManager);
77
78
        $response = $next($request->withAttribute(static::SESSION_KEY, $this->session), $response);
79
80
        $response = $this->respondWithSessionCookie($response);
81
82
        $this->session->close();
83
84
        return $response;
85
    }
86
87
    /**
88
     * Add session cookie Set-Cookie header to response.
89
     *
90
     * @param ResponseInterface $response
91
     *
92
     * @return ResponseInterface
93
     */
94
    protected function respondWithSessionCookie(ResponseInterface $response)
95
    {
96
        if (!$this->session->isActive()) {
97
            // @codeCoverageIgnoreStart
98
            return $response;
99
            // @codeCoverageIgnoreEnd
100
        }
101
102
        $configuration = $this->getConfiguration();
103
104
        $timeoutKey = $configuration->getTimeoutKey();
105
        $expireTime = $this->session->has($timeoutKey)
106
            ? $this->session->get($timeoutKey)
107
            : time() - $configuration->getLifetime();
108
109
        return $response->withAddedHeader(
110
            'Set-Cookie',
111
            sprintf(
112
                '%s=%s; %s',
113
                urlencode($configuration->getName()),
114
                urlencode($this->session->getId()),
115
                $this->getSessionCookieParameters($expireTime)
116
            )
117
        );
118
    }
119
120
    /**
121
     * Get session cookie parameters.
122
     *
123
     * @param int $expireTime
124
     *
125
     * @return string
126
     */
127
    protected function getSessionCookieParameters($expireTime)
128
    {
129
        $configuration = $this->getConfiguration();
130
131
        $cookieParams = [
132
            sprintf(
133
                'expires=%s; max-age=%s',
134
                gmdate('D, d M Y H:i:s T', $expireTime),
135
                $configuration->getLifetime()
136
            ),
137
        ];
138
139
        if (!empty($configuration->getCookiePath())) {
140
            $cookieParams[] = 'path=' . $configuration->getCookiePath();
141
        }
142
143
        if (!empty($configuration->getCookieDomain())) {
144
            $cookieParams[] = 'domain=' . $configuration->getCookieDomain();
145
        }
146
147
        if ($configuration->isCookieSecure()) {
148
            $cookieParams[] = 'secure';
149
        }
150
151
        if ($configuration->isCookieHttpOnly()) {
152
            $cookieParams[] = 'httponly';
153
        }
154
155
        return implode('; ', $cookieParams);
156
    }
157
158
    /**
159
     * Get session configuration.
160
     *
161
     * @return Configuration
162
     */
163
    protected function getConfiguration()
164
    {
165
        return $this->sessionManager->getConfiguration();
166
    }
167
}
168