Passed
Branch master (3daac1)
by Vincent
07:53
created

HttpFieldPath::add()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Bdf\Form\Child\Http;
4
5
/**
6
 * Represents the HTTP field path to build
7
 * Handles prefix and array key fields
8
 *
9
 * Note: This class is immutable, any modifier will return a new instance
10
 *
11
 * <code>
12
 * $path = HttpFieldPath::named('root'); // Create the root field
13
 * echo $path->get(); // "root"
14
 * echo $path->add('bar')->get(); // Array element field : "root[bar]"
15
 * echo $path->prefix('p_')->add('bar')->get(); // Add a prefix for the sub element : "root[p_bar]"
16
 * </code>
17
 */
18
final class HttpFieldPath
19
{
20
    /**
21
     * @var HttpFieldPath|null
22
     */
23
    private static $empty;
24
25
    /**
26
     * @var string
27
     */
28
    private $path = '';
29
30
    /**
31
     * @var string
32
     */
33
    private $prefix = '';
34
35
    /**
36
     * HttpFieldPath constructor.
37
     * Note: prefer use the static methods instead of the constructor
38
     *
39
     * @param string $path The path
40
     * @param string $prefix The prefix
41
     */
42 42
    public function __construct(string $path = '', string $prefix = '')
43
    {
44 42
        $this->path = $path;
45 42
        $this->prefix = $prefix;
46 42
    }
47
48
    /**
49
     * Add a new sub array key to the field path :
50
     * - If the current path is the root (i.e. empty path), will return a path consisting of the name
51
     * - If the path is not the root (i.e. not empty path), the name will be added at end, enclosed by "[]"
52
     * - In any case, if there is a prefix, it will be added before the name
53
     *
54
     * @param string $name The element name to add
55
     *
56
     * @return static The new path instance
57
     */
58 16
    public function add(string $name): self
59
    {
60 16
        $newPath = clone $this;
61
62 16
        $newPath->path = empty($this->path) ? $this->prefix.$name : $this->path.'['.$this->prefix.$name.']';
63 16
        $newPath->prefix = '';
64
65 16
        return $newPath;
66
    }
67
68
    /**
69
     * Add a prefix for the next element
70
     * The prefix will be appended at the end of previous prefixes, so when chaining prefixed, the prefixes order will be kept
71
     *
72
     * @param string $name
73
     *
74
     * @return static The new path instance
75
     */
76 6
    public function prefix(string $name): self
77
    {
78 6
        $newPath = clone $this;
79
80 6
        $newPath->prefix .= $name;
81
82 6
        return $newPath;
83
    }
84
85
    /**
86
     * Get the string value of the path
87
     *
88
     * @return string
89
     */
90 42
    public function get(): string
91
    {
92 42
        if (empty($this->path)) {
93 7
            return $this->prefix;
94
        }
95
96 40
        if (empty($this->prefix)) {
97 39
            return $this->path;
98
        }
99
100 2
        return $this->path.'['.$this->prefix.']';
101
    }
102
103
    /**
104
     * Call ->get()
105
     *
106
     * @return string
107
     */
108 37
    public function __toString(): string
109
    {
110 37
        return $this->get();
111
    }
112
113
    /**
114
     * Get the empty path (i.e. root path)
115
     *
116
     * @return HttpFieldPath
117
     */
118 1
    public static function empty(): HttpFieldPath
119
    {
120 1
        if (self::$empty) {
121 1
            return self::$empty;
122
        }
123
124 1
        return self::$empty = new HttpFieldPath();
125
    }
126
127
    /**
128
     * Get a simple path consisting of the name
129
     *
130
     * @param string $name
131
     *
132
     * @return HttpFieldPath
133
     */
134 35
    public static function named(string $name): HttpFieldPath
135
    {
136 35
        return new HttpFieldPath($name);
137
    }
138
139
    /**
140
     * Get a path with a prefix
141
     *
142
     * @param string $prefix
143
     *
144
     * @return HttpFieldPath
145
     */
146 6
    public static function prefixed(string $prefix): HttpFieldPath
147
    {
148 6
        return new HttpFieldPath('', $prefix);
149
    }
150
}
151