PathMapper::map()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 26
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 13
cts 13
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 11
nc 5
nop 1
crap 6
1
<?php
2
3
namespace TreeHouse\Feeder\Modifier\Item\Mapper;
4
5
use Symfony\Component\HttpFoundation\ParameterBag;
6
7
/**
8
 * Performs deep path search in ParameterBag.
9
 * This supports fields like: foo[bar][baz].
10
 */
11
class PathMapper implements MapperInterface
12
{
13
    /**
14
     * @var array<string, string>
15
     */
16
    protected $mapping = [];
17
18
    /**
19
     * Whether to use deep path search. This supports fields like: foo[bar][baz].
20
     *
21
     * @var bool
22
     */
23
    protected $deep = true;
24
25
    /**
26
     * @param array $mapping The mapping
27
     * @param bool  $deep    Whether to use deep path search. This supports fields like: foo[bar][baz]
28
     */
29 14
    public function __construct(array $mapping = [], $deep = true)
30
    {
31 14
        $this->deep = $deep;
32 14
        $this->set($mapping);
33 14
    }
34
35
    /**
36
     * @inheritdoc
37
     */
38 8
    public function map(ParameterBag $item)
39
    {
40 8
        foreach ($this->mapping as $from => $to) {
41
            // use a special kind of null value to check, because we do want a
42
            // `null` value if it's actually set, but we cannot use the has()
43
            // method on deep paths, like foo[bar]
44 8
            if ('__null__' === $value = $item->get($from, '__null__', $this->deep)) {
45 2
                continue;
46
            }
47
48
            // if value is null, only set it when we don't already have this value
49 8
            if ($item->has($to) && !$this->mayOverride($item->get($to), $value)) {
50 2
                $item->remove($from);
51 2
                continue;
52
            }
53
54 8
            $item->set($to, $value);
55
56
            // remove the original if the key is mapped to a different key
57 8
            if ($to !== $from) {
58 8
                $item->remove($from);
59 8
            }
60 8
        }
61
62 8
        return $item;
63
    }
64
65
    /**
66
     * @param string $fromField
67
     * @param string $toField
68
     */
69 2
    public function add($fromField, $toField)
70
    {
71 2
        $this->mapping[$fromField] = $toField;
72 2
    }
73
74
    /**
75
     * @param array<string, string> $mapping
76
     */
77 14
    public function set(array $mapping)
78
    {
79 14
        $this->mapping = $mapping;
80 14
    }
81
82
    /**
83
     * @param string $fromField
84
     *
85
     * @return string|null
86
     */
87 4
    public function mapToField($fromField)
88
    {
89 4
        return array_key_exists($fromField, $this->mapping) ? $this->mapping[$fromField] : null;
90
    }
91
92
    /**
93
     * @param string $toField
94
     *
95
     * @return string|null
96
     */
97 4
    public function mapFromField($toField)
98
    {
99 4
        if (false !== $key = array_search($toField, $this->mapping)) {
100 4
            return $key;
101
        }
102
103 2
        return null;
104
    }
105
106
    /**
107
     * Decides whether a value may override a previous value.
108
     *
109
     * @param mixed $previous
110
     * @param mixed $value
111
     *
112
     * @return bool
113
     *
114
     * @todo implement override strategy with options: keep and override
115
     */
116 6
    protected function mayOverride($previous, $value)
117
    {
118 6
        return !empty($value) || empty($previous);
119
    }
120
}
121