Passed
Pull Request — master (#22)
by Aleksei
02:32
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 23
    public function getDirective(): string
54
    {
55 23
        return $this->directive;
56
    }
57 1
    public function getValue(): string
58
    {
59 1
        return $this->getDirective();
60
    }
61
62
    public function hasArgument(): bool
63
    {
64
        return $this->argument !== null;
65
    }
66 22
    public function getArgument(): ?string
67
    {
68 22
        return $this->argument;
69
    }
70
    public function getArgumentList(): array
71
    {
72
        return $this->argument === null ? [] : explode(',', $this->argument);
73
    }
74
75
    /**
76
     * @param string $directive
77
     * @param string|null $argument
78
     *
79
     * @throws InvalidArgumentException
80
     */
81 42
    public function withDirective(string $directive, string $argument = null): self
82
    {
83 42
        $clone = clone $this;
84 42
        $clone->setDirective($directive, $argument, true);
85 29
        return $clone;
86
    }
87
88 45
    protected function setValue(string $value): void
89
    {
90 45
        $this->setDirective($value);
91 45
    }
92 45
    private function setDirective(string $value, string $argument = null, bool $trowError = false): bool
93
    {
94 45
        $name = strtolower($value);
95
96 45
        $argumentType = static::DIRECTIVES[$name] ?? self::ARG_CUSTOM;
97
98 45
        $writeProperties = function (\Exception $err = null, string $arg = null, int $type = self::ARG_EMPTY) use (
99 45
            $name,
100 45
            $trowError
101
        ) {
102 45
            if ($trowError && $err !== null) {
103 13
                throw $err;
104
            }
105 45
            $this->directive = $name;
106 45
            $this->argument = $arg;
107 45
            $this->argumentType = $type;
108 45
            $this->error = $err;
109 45
            return $this->error === null;
110 45
        };
111
112 45
        if ($argument === null && ($argumentType & self::ARG_EMPTY) === self::ARG_EMPTY) {
113 5
            return $writeProperties();
114 45
        } elseif ($argumentType === self::ARG_EMPTY) {
115 1
            if ($argument !== null) {
116 1
                return $writeProperties(new InvalidArgumentException("{$name} directive should not have an argument"));
117
            }
118
            return $writeProperties();
119 45
        } elseif (($argumentType & self::ARG_HEADERS_LIST) === self::ARG_HEADERS_LIST) {
120
            // Validate headers list
121 12
            $argument = $argument === null ? null : trim($argument);
122 12
            if ($argument === null || preg_match('/^[\\w\\-]+(?:(?:\\s*,\\s*)[\\w\\-]+)*$/', $argument) !== 1) {
123 6
                return $writeProperties(
124 6
                    new InvalidArgumentException(
125 6
                        "{$name} directive should have an argument as a comma separated headers name list"
126
                    )
127
                );
128
            }
129 6
            return $writeProperties(null, $argument, self::ARG_HEADERS_LIST);
130 45
        } elseif (($argumentType & self::ARG_DELTA_SECONDS) === self::ARG_DELTA_SECONDS) {
131 10
            $this->argumentType = self::ARG_DELTA_SECONDS;
132
            // Validate number
133 10
            if ($argument === null || preg_match('/^\\d+$/', $argument) !== 1) {
134 6
                return $writeProperties(
135 6
                    new InvalidArgumentException("{$name} directive should have numeric argument"),
136 6
                    '0',
137 6
                    self::ARG_DELTA_SECONDS
138
                );
139
            }
140 4
            return $writeProperties(null, $argument, self::ARG_DELTA_SECONDS);
141
        }
142 45
        return $writeProperties(null, $argument, $argumentType);
143
    }
144
}
145