Completed
Push — master ( 5592f8...cdb5f1 )
by BENOIT
01:22
created

Pairs::getIterator()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 7
nop 0
dl 0
loc 30
rs 8.8177
c 0
b 0
f 0
1
<?php
2
3
namespace BenTools\QueryString;
4
5
use IteratorAggregate;
6
use Traversable;
7
8
final class Pairs implements IteratorAggregate
9
{
10
    /**
11
     * @var string
12
     */
13
    private $queryString;
14
15
    /**
16
     * @var bool
17
     */
18
    private $decodeKeys;
19
20
    /**
21
     * @var bool
22
     */
23
    private $decodeValues;
24
25
    /**
26
     * @var null|string
27
     */
28
    private $separator;
29
30
    /**
31
     * Pairs constructor.
32
     */
33
    public function __construct(
34
        string $queryString,
35
        bool $decodeKeys = false,
36
        bool $decodeValues = false,
37
        string $separator = null
38
    ) {
39
40
        $this->queryString = $queryString;
41
        $this->decodeKeys = $decodeKeys;
42
        $this->decodeValues = $decodeValues;
43
        $this->separator = $separator;
44
    }
45
46
    /**
47
     * @param string $queryString
48
     * @return Pairs
49
     */
50
    public function withQueryString(string $queryString): self
51
    {
52
        $clone = clone $this;
53
        $clone->queryString = $queryString;
54
        return $clone;
55
    }
56
57
    /**
58
     * @param bool $decodeKeys
59
     * @return Pairs
60
     */
61
    public function withDecodeKeys(bool $decodeKeys): self
62
    {
63
        $clone = clone $this;
64
        $clone->decodeKeys = $decodeKeys;
65
        return $clone;
66
    }
67
68
    /**
69
     * @param bool $decodeValues
70
     * @return Pairs
71
     */
72
    public function withDecodeValues(bool $decodeValues): self
73
    {
74
        $clone = clone $this;
75
        $clone->decodeValues = $decodeValues;
76
        return $clone;
77
    }
78
79
    /**
80
     * @param null|string $separator
81
     * @return Pairs
82
     */
83
    public function withSeparator(?string $separator): self
84
    {
85
        $clone = clone $this;
86
        $clone->separator = $separator;
87
        return $clone;
88
    }
89
90
    /**
91
     * @return Traversable
92
     */
93
    public function getIterator(): Traversable
94
    {
95
        if ('' === trim($this->queryString)) {
96
            return;
97
        }
98
99
        $separator = $this->separator ?? ini_get('arg_separator.input');
100
101
        if ('' === $separator) {
102
            throw new \RuntimeException("A separator cannot be blank.");
103
        }
104
105
        $pairs = explode($separator, $this->queryString);
106
107
        foreach ($pairs as $pair) {
108
            $keyValue = explode('=', $pair);
109
            $key = $keyValue[0];
110
            $value = $keyValue[1] ?? null;
111
112
            if (true === $this->decodeKeys) {
113
                $key = urldecode($key);
114
            }
115
116
            if (true === $this->decodeValues) {
117
                $value = urldecode($value);
118
            }
119
120
            yield $key => $value;
121
        }
122
    }
123
124
    /**
125
     * @return string
126
     */
127
    public function __toString(): string
128
    {
129
        return (string) $this->queryString;
130
    }
131
}
132