Passed
Push — master ( 3d26d2...ccfa1e )
by Richard
07:28 queued 11s
created

xoops_buildCookieHeader()   C

Complexity

Conditions 14
Paths 96

Size

Total Lines 39
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 21
c 1
b 0
f 0
nc 96
nop 1
dl 0
loc 39
rs 6.2666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits of supporting
4
 developers from this source code or any supporting source code which is considered
5
 copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
/**
13
 * Near drop-in replacement for PHP's setcookie()
14
 *
15
 * @copyright       Copyright 2021 The XOOPS Project https://xoops.org
16
 * @license         GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
17
 * @author          Richard Griffith <[email protected]>
18
 *
19
 * This exists to bring samesite support to php versions before 7.3, and
20
 * it treats the default as samesite=strict
21
 *
22
 * It supports both of the two declared signatures:
23
 * - setcookie ( string $name , string $value = "" , int $expires = 0 , string $path = "" , string $domain = "" , bool $secure = false , bool $httponly = false ) : bool
24
 * - setcookie ( string $name , string $value = "" , array $options = [] ) : bool
25
 */
26
function xoops_setcookie()
27
{
28
    if (headers_sent()) {
29
        return false;
30
    }
31
    $argNames    = array('name', 'value', 'expires', 'path', 'domain', 'secure', 'httponly');
32
    //$argDefaults = array(null,   '',       0,        '',     '',        false,    false);
33
    //$optionsKeys = array('expires', 'path', 'domain', 'secure', 'httponly', 'samesite');
34
    $rawArgs = func_get_args();
35
    $args = array();
36
    foreach ($rawArgs as $key => $value) {
37
        if (2 === $key && is_array($value)) {
38
            // modern call
39
            $args['options'] = array();
40
            foreach ($value as $optionKey => $optionValue) {
41
                $args['options'][strtolower($optionKey)] = $optionValue;
42
            }
43
            break;
44
        }
45
        if ($key>1) {
46
            if (null !== $value) {
47
                $args['options'][$argNames[$key]] = $value;
48
            }
49
        } else {
50
            $args[$argNames[$key]] = $value;
51
        }
52
    }
53
54
    // make samesite=strict the default
55
    $args['options']['samesite'] = isset($args['options']['samesite']) ? $args['options']['samesite'] : 'strict';
56
57
    // after php 7.3 we just let php do it
58
    if (PHP_VERSION_ID >= 70300) {
59
        return setcookie($args['name'], $args['value'], $args['options']);
60
    }
61
    // render and send our own headers below php 7.3
62
    header(xoops_buildCookieHeader($args), false);
63
    return true;
64
}
65
66
/**
67
 * @param array $args 'name', 'value' and 'options' corresponding to php 7.3 arguments to setcookie()
68
 *
69
 * @return string
70
 */
71
function xoops_buildCookieHeader($args)
72
{
73
    //$optionsKeys = array('expires', 'path', 'domain', 'secure', 'httponly', 'samesite');
74
    $options = $args['options'];
75
76
    $header = 'Set-Cookie: ' . $args['name'] . '=' . rawurlencode($args['value']) . ' ';
77
78
    if (isset($options['expires']) && 0 !== $options['expires']) {
79
        $dateTime = new DateTime();
80
        if (time() >= $options['expires']) {
81
            $dateTime->setTimestamp(0);
82
            $header = 'Set-Cookie: ' . $args['name'] . '=deleted ; expires=' . $dateTime->format(DateTime::COOKIE) . ' ; Max-Age=0 ';
83
        } else {
84
            $dateTime->setTimestamp($options['expires']);
85
            $header .= '; expires=' . $dateTime->format(DateTime::COOKIE) . ' ';
86
        }
87
    }
88
89
    if (isset($options['path']) && '' !== $options['path']) {
90
        $header .= '; path=' . $options['path'] . ' ';
91
    }
92
93
    if (isset($options['domain']) && '' !== $options['domain']) {
94
        $header .= '; domain=' . $options['domain'] . ' ';
95
    }
96
97
    if (isset($options['secure']) && true === (bool) $options['secure']) {
98
        $header .= '; Secure ';
99
    }
100
101
    if (isset($options['httponly']) && true === (bool) $options['httponly']) {
102
        $header .= '; HttpOnly ';
103
    }
104
105
    if (isset($options['samesite']) && '' !== $options['samesite']) {
106
        $header .= '; samesite=' . $options['samesite'] . ' ';
107
    }
108
109
    return $header;
110
}
111