Passed
Push — master ( c3a704...42d0c7 )
by Andreas
24:45
created

multipleTransformer::transform()   B

Complexity

Conditions 10
Paths 10

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 11.097

Importance

Changes 0
Metric Value
cc 10
eloc 18
nc 10
nop 1
dl 0
loc 30
ccs 14
cts 18
cp 0.7778
crap 11.097
rs 7.6666
c 0
b 0
f 0

How to fix   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
 * @copyright CONTENT CONTROL GmbH, http://www.contentcontrol-berlin.de
4
 */
5
6
namespace midcom\datamanager\extension\transformer;
7
8
use Symfony\Component\Form\DataTransformerInterface;
9
use Symfony\Component\Form\Exception\TransformationFailedException;
10
use midcom_error;
11
12
/**
13
 * Experimental jsdate transformer
14
 */
15
class multipleTransformer implements DataTransformerInterface
16
{
17
    private $config;
18
19
    private $multiple_separator = '|';
20
21
    private $multiple_storagemode = 'serialized';
22
23
    /**
24
     * This member contains the other key, in case it is set. In case of multiselects,
25
     * the full list of unknown keys is collected here, in case of single select, this value
26
     * takes precedence from the standard selection.
27
     *
28
     * This is only valid if the allow_other flag is set.
29
     * TODO: still to be implentend
30
     * @var string
31
     */
32
    private $others = [];
33
34 33
    public function __construct(array $config)
35
    {
36 33
        $this->config = $config;
37 33
        if (!empty($this->config['type_config']['multiple_storagemode'])) {
38 32
            $this->multiple_storagemode = $this->config['type_config']['multiple_storagemode'];
39
        }
40 33
    }
41
42 29
    public function transform($input)
43
    {
44 29
        if (in_array($input, [false, null], true)) {
45 26
            return [];
46
        }
47
48 18
        switch ($this->multiple_storagemode) {
49 18
            case 'serialized':
50 14
            case 'array':
51 4
                if (empty($input)) {
52 1
                    return [];
53
                }
54
55 3
                return unserialize($input);
56
57 14
            case 'imploded':
58
                if (!is_string($input)) {
59
                    return [];
60
                }
61
                return explode($this->multiple_separator, $input);
62
63 14
            case 'imploded_wrapped':
64 14
                if (!is_string($input) || substr($input, 1, -1) == '') {
65 13
                    return [];
66
                }
67
68 1
                return explode($this->multiple_separator, substr($input, 1, -1));
69
70
            default:
71
                throw new midcom_error("The multiple_storagemode '{$this->multiple_storagemode}' is invalid, cannot continue.");
72
        }
73
    }
74
75 5
    public function reverseTransform($array)
76
    {
77 5
        if (!is_array($array) ) {
78
            throw new TransformationFailedException('Expected an array.');
79
        }
80
81 5
        if (empty($array)) {
82 3
            return;
83
        }
84
85 2
        switch ($this->multiple_storagemode) {
86 2
            case 'array':
87
                return $array;
88
89 2
            case 'serialized':
90 1
                if ($this->others) {
91
                    return array_merge($array, $this->others);
0 ignored issues
show
Bug introduced by
$this->others of type string is incompatible with the type array expected by parameter $arrays of array_merge(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
                    return array_merge($array, /** @scrutinizer ignore-type */ $this->others);
Loading history...
92
                }
93 1
                return serialize($array);
94
95 1
            case 'imploded':
96
                return $this->get_imploded_options($array);
97
98 1
            case 'imploded_wrapped':
99 1
                $glue = $this->multiple_separator;
100 1
                $options = $this->get_imploded_options($array);
101 1
                return "{$glue}{$options}{$glue}";
102
103
            default:
104
                throw new TransformationFailedException('Invalid storage mode ' . $this->multiple_storagemode);
105
        }
106
    }
107
108
    /**
109
     * Prepares the imploded storage string. All entries containing the pipe char (used as glue)
110
     * will be logged and skipped silently.
111
     */
112 1
    private function get_imploded_options(array $array) : string
113
    {
114 1
        $glue = $this->multiple_separator;
115
116 1
        if ($this->others) {
117
            if (is_string($this->others)) {
0 ignored issues
show
introduced by
The condition is_string($this->others) is always true.
Loading history...
118
                $this->others = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array($this->others => $this->others) of type array<string,string> is incompatible with the declared type string of property $others.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
119
                    $this->others => $this->others,
120
                ];
121
            }
122
            $options = array_merge($array, $this->others);
123
        } else {
124 1
            $options = $array;
125
        }
126
127 1
        $result = [];
128 1
        foreach ($options as $key) {
129 1
            if (str_contains($key, $glue)) {
130
                debug_add("The option key '{$key}' contained the multiple separator ($this->multiple_storagemode) char, which is not allowed for imploded storage targets. ignoring silently.",
131
                MIDCOM_LOG_WARN);
132
                continue;
133
            }
134
135 1
            $result[] = $key;
136
        }
137 1
        return implode($glue, $result);
138
    }
139
}
140