Passed
Pull Request — master (#22)
by Aleksei
07:47
created

DirectivesHeaderValue::setDirective()   C

Complexity

Conditions 14
Paths 10

Size

Total Lines 51
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 35
CRAP Score 14.0042

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 14
eloc 34
c 1
b 0
f 1
nc 10
nop 3
dl 0
loc 51
ccs 35
cts 36
cp 0.9722
crap 14.0042
rs 6.2666

How to fix   Long Method    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
declare(strict_types=1);
4
5
namespace Yiisoft\Http\Header\Internal;
6
7
use InvalidArgumentException;
8
use Yiisoft\Http\Header\DirectiveHeader;
9
10
abstract class DirectivesHeaderValue extends BaseHeaderValue
11
{
12
    protected const DIRECTIVES = [];
13
14
    protected const ARG_EMPTY = 1;
15
    protected const ARG_DELTA_SECONDS = 2;
16
    protected const ARG_HEADERS_LIST = 4;
17
    protected const ARG_CUSTOM = 8;
18
19
    protected string $directive = '';
20
    protected ?string $argument = null;
21
    protected int $argumentType = self::ARG_EMPTY;
22
23 31
    public function __toString(): string
24
    {
25 31
        if ($this->directive === '') {
26 1
            return '';
27
        }
28 30
        if ($this->argument === null) {
29 9
            return $this->directive;
30
        }
31 22
        if ($this->argumentType === self::ARG_HEADERS_LIST) {
32 6
            return "{$this->directive}=\"{$this->argument}\"";
33
        }
34 16
        if ($this->argumentType === self::ARG_CUSTOM) {
35 12
            $argument = $this->encodeQuotedString($this->argument);
36
            if (
37 12
                $argument === ''
38 11
                || strlen($argument) !== strlen($this->argument)
39 12
                || preg_match('/[^a-z0-9_]/i', $argument) === 1
40
            ) {
41 7
                $argument = '"' . $argument . '"';
42
            }
43 12
            return "{$this->directive}={$argument}";
44
        }
45 4
        return "{$this->directive}={$this->argument}";
46
    }
47
48 1
    public static function createHeader(): DirectiveHeader
49
    {
50 1
        return new DirectiveHeader(static::class);
51
    }
52
53
    /**
54
     * @return string|null Returns null if the directive is not defined or cannot be parsed without error
55
     */
56 23
    public function getDirective(): string
57
    {
58 23
        return $this->directive;
59
    }
60 1
    public function getValue(): string
61
    {
62 1
        return $this->getDirective();
63
    }
64
65
    public function hasArgument(): bool
66
    {
67
        return $this->argument !== null;
68
    }
69 22
    public function getArgument(): ?string
70
    {
71 22
        return $this->argument;
72
    }
73
    public function getArgumentList(): array
74
    {
75
        return $this->argument === null ? [] : explode(',', $this->argument);
76
    }
77
78
    /**
79
     * @param string $directive
80
     * @param string|null $argument
81
     *
82
     * @throws InvalidArgumentException
83
     */
84 42
    public function withDirective(string $directive, string $argument = null): self
85
    {
86 42
        $clone = clone $this;
87 42
        $clone->setDirective($directive, $argument, true);
88 29
        return $clone;
89
    }
90
91 45
    protected function setValue(string $value): void
92
    {
93 45
        $this->setDirective($value);
94 45
    }
95 45
    private function setDirective(string $value, string $argument = null, bool $trowError = false): bool
96
    {
97 45
        $name = strtolower($value);
98
99 45
        $argumentType = static::DIRECTIVES[$name] ?? self::ARG_CUSTOM;
100
101 45
        $writeProperties = function (\Exception $err = null, string $arg = null, int $type = self::ARG_EMPTY) use (
102 45
            $name,
103 45
            $trowError
104
        ) {
105 45
            if ($trowError && $err !== null) {
106 13
                throw $err;
107
            }
108 45
            $this->directive = $name;
109 45
            $this->argument = $arg;
110 45
            $this->argumentType = $type;
111 45
            $this->error = $err;
112 45
            return $this->error === null;
113 45
        };
114
115 45
        if ($argument === null && ($argumentType & self::ARG_EMPTY) === self::ARG_EMPTY) {
116 5
            return $writeProperties();
117 45
        } elseif ($argumentType === self::ARG_EMPTY) {
118 1
            if ($argument !== null) {
119 1
                return $writeProperties(new InvalidArgumentException("{$name} directive should not have an argument"));
120
            }
121
            return $writeProperties();
122 45
        } elseif (($argumentType & self::ARG_HEADERS_LIST) === self::ARG_HEADERS_LIST) {
123
            // Validate headers list
124 12
            $argument = $argument === null ? null : trim($argument);
125 12
            if ($argument === null || preg_match('/^[\\w\\-]+(?:(?:\\s*,\\s*)[\\w\\-]+)*$/', $argument) !== 1) {
126 6
                return $writeProperties(
127 6
                    new InvalidArgumentException(
128 6
                        "{$name} directive should have an argument as a comma separated headers name list"
129
                    )
130
                );
131
            }
132 6
            return $writeProperties(null, $argument, self::ARG_HEADERS_LIST);
133 45
        } elseif (($argumentType & self::ARG_DELTA_SECONDS) === self::ARG_DELTA_SECONDS) {
134 10
            $this->argumentType = self::ARG_DELTA_SECONDS;
135
            // Validate number
136 10
            if ($argument === null || preg_match('/^\\d+$/', $argument) !== 1) {
137 6
                return $writeProperties(
138 6
                    new InvalidArgumentException("{$name} directive should have numeric argument"),
139 6
                    '0',
140 6
                    self::ARG_DELTA_SECONDS
141
                );
142
            }
143 4
            return $writeProperties(null, $argument, self::ARG_DELTA_SECONDS);
144
        }
145 45
        return $writeProperties(null, $argument, $argumentType);
146
    }
147
}
148