Completed
Push — master ( 32e652...8e829c )
by Neomerx
11:56
created

CookieMiddleware::handle()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 39
c 0
b 0
f 0
rs 8.5806
cc 4
eloc 21
nc 2
nop 3
1
<?php namespace Limoncello\Application\Packages\Cookies;
2
3
/**
4
 * Copyright 2015-2017 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Closure;
20
use Limoncello\Contracts\Application\MiddlewareInterface;
21
use Limoncello\Contracts\Cookies\CookieInterface;
22
use Limoncello\Contracts\Cookies\CookieJarInterface;
23
use Psr\Container\ContainerInterface;
24
use Psr\Http\Message\ResponseInterface;
25
use Psr\Http\Message\ServerRequestInterface;
26
27
/**
28
 * @package Limoncello\Application
29
 */
30
class CookieMiddleware implements MiddlewareInterface
31
{
32
    /**
33
     * A callable to set an ordinary (encoded) cookie.
34
     */
35
    protected const SET_COOKIE_CALLABLE = '\setcookie';
36
37
    /**
38
     * A callable to set a raw (not encoded) cookie.
39
     */
40
    protected const SET_RAW_COOKIE_CALLABLE = '\setrawcookie';
41
42
    /**
43
     * @inheritdoc
44
     */
45
    public static function handle(
46
        ServerRequestInterface $request,
47
        Closure $next,
48
        ContainerInterface $container
49
    ): ResponseInterface {
50
        /** @var ResponseInterface $response */
51
        $response = $next($request);
52
53
        if ($container->has(CookieJarInterface::class) === true) {
54
            /** @var CookieJarInterface $cookieJar */
55
            $cookieJar = $container->get(CookieJarInterface::class);
56
            foreach ($cookieJar->getAll() as $cookie) {
57
                /** @var CookieInterface $cookie */
58
59
                // The reason why methods for setting cookies are called with call_user_func and their names
60
                // is that calling `setcookie` is not possible during testing. It can't add any headers
61
                // in a console app which produces some output.
62
                //
63
                // Using functions by names allows replace them with test mocks and check input values.
64
                //
65
                // Notice constants are used with `static::`. Their values can and will be replaced in tests.
66
                $setCookieFunction =
67
                    $cookie->getIsNotRaw() === true ? static::SET_COOKIE_CALLABLE : static::SET_RAW_COOKIE_CALLABLE;
68
69
                call_user_func(
70
                    $setCookieFunction,
71
                    $cookie->getName(),
72
                    $cookie->getValue(),
73
                    $cookie->getExpiresAtUnixTime(),
74
                    $cookie->getPath(),
75
                    $cookie->getDomain(),
76
                    $cookie->getSendOnlyOverSecureConnection(),
77
                    $cookie->getAccessibleOnlyThroughHttp()
78
                );
79
            }
80
        }
81
82
        return $response;
83
    }
84
}
85