Completed
Pull Request — master (#8)
by Joao
06:41
created

Row   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 94.17%

Importance

Changes 0
Metric Value
wmc 41
lcom 1
cbo 2
dl 0
loc 272
ccs 97
cts 103
cp 0.9417
rs 9.1199
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 3
A addField() 0 11 3
A get() 0 13 3
A getAsArray() 0 14 3
A getFieldNames() 0 4 1
A set() 0 9 2
A removeField() 0 7 2
A removeValue() 0 19 5
A replaceValue() 0 17 5
A getAsDom() 0 19 5
A toArray() 0 4 1
A getAsJSON() 0 10 2
A getAsRaw() 0 4 1
A hasChanges() 0 4 1
A acceptChanges() 0 4 1
A rejectChanges() 0 4 1
A informChanges() 0 4 1
A setPropValue() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Row often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Row, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace ByJG\AnyDataset\Core;
4
5
use ByJG\Serializer\BinderObject;
6
use ByJG\Serializer\DumpToArrayInterface;
7
use ByJG\Util\XmlUtil;
8
use UnexpectedValueException;
9
10
class Row extends BinderObject implements DumpToArrayInterface
11
{
12
13
    /**
14
     * \DOMNode represents a Row
15
     * @var \DOMElement
16
     */
17
    private $node = null;
18
    private $row = null;
19
    private $originalRow = null;
20
21
    /**
22
     * Row constructor
23
     *
24
     * @param array()
25
     * @throws \ByJG\Serializer\Exception\InvalidArgumentException
26
     */
27 35
    public function __construct($instance = null)
28
    {
29 35
        if (is_null($instance)) {
30 33
            $this->row = array();
31 9
        } elseif (is_array($instance)) {
32 5
            $this->row = $instance;
33
        } else {
34 4
            $this->row = array();
35 4
            $this->bind($instance);
36
        }
37
38 35
        $this->acceptChanges();
39 35
    }
40
41
    /**
42
     * Add a string field to row
43
     * @param string $name
44
     * @param string $value
45
     */
46 31
    public function addField($name, $value)
47
    {
48 31
        if (!array_key_exists($name, $this->row)) {
49 31
            $this->row[$name] = $value;
50 14
        } elseif (is_array($this->row[$name])) {
51 14
            $this->row[$name][] = $value;
52
        } else {
53 14
            $this->row[$name] = array($this->row[$name], $value);
54
        }
55 31
        $this->informChanges();
56 31
    }
57
58
    /**
59
     * @param string $name - Field name
60
     * @return string
61
     * @desc et the string value from a field name
62
     */
63 15
    public function get($name)
64
    {
65 15
        if (!array_key_exists($name, $this->row)) {
66 4
            return null;
67
        }
68
69 15
        $result = $this->row[$name];
70 15
        if (is_array($result)) {
71 2
            return array_shift($result);
72
        } else {
73 14
            return $result;
74
        }
75
    }
76
77
    /**
78
     * Get array from a single field
79
     *
80
     * @param string $fieldName
81
     * @return array
82
     */
83 3
    public function getAsArray($fieldName)
84
    {
85 3
        if (!array_key_exists($fieldName, $this->row)) {
86
            return [];
87
        }
88
89 3
        $result = $this->row[$fieldName];
90
91 3
        if (empty($result)) {
92 1
            return [];
93
        }
94
95 3
        return (array)$result;
96
    }
97
98
    /**
99
     * Return all Field Names from current Row
100
     * @return array
101
     */
102 1
    public function getFieldNames()
103
    {
104 1
        return array_keys($this->row);
105
    }
106
107
    /**
108
     * Set a string value to existing field name
109
     * @param string $name
110
     * @param string $value
111
     */
112 9
    public function set($name, $value)
113
    {
114 9
        if (!array_key_exists($name, $this->row)) {
115 5
            $this->addField($name, $value);
116
        } else {
117 5
            $this->row[$name] = $value;
118
        }
119 9
        $this->informChanges();
120 9
    }
121
122
    /**
123
     * Remove specified field name from row.
124
     *
125
     * @param string $fieldName
126
     */
127 2
    public function removeField($fieldName)
128
    {
129 2
        if (array_key_exists($fieldName, $this->row)) {
130 2
            unset($this->row[$fieldName]);
131 2
            $this->informChanges();
132
        }
133 2
    }
134
135
    /**
136
     * Remove specified field name with specified value name from row.
137
     *
138
     * @param string $fieldName
139
     * @param $value
140
     */
141 1
    public function removeValue($fieldName, $value)
142
    {
143 1
        $result = $this->row[$fieldName];
144 1
        if (!is_array($result)) {
145 1
            if ($value == $result) {
146 1
                unset($this->row[$fieldName]);
147 1
                $this->informChanges();
148
            }
149
        } else {
150 1
            $qty = count($result);
151 1
            for ($i = 0; $i < $qty; $i++) {
152 1
                if ($result[$i] == $value) {
153 1
                    unset($result[$i]);
154 1
                    $this->informChanges();
155
                }
156
            }
157 1
            $this->row[$fieldName] = array_values($result);
158
        }
159 1
    }
160
161
    /**
162
     * Update a specific field and specific value with new value
163
     *
164
     * @param String $fieldName
165
     * @param String $oldvalue
166
     * @param String $newvalue
167
     */
168 1
    public function replaceValue($fieldName, $oldvalue, $newvalue)
169
    {
170 1
        $result = $this->row[$fieldName];
171 1
        if (!is_array($result)) {
172 1
            if ($oldvalue == $result) {
173 1
                $this->row[$fieldName] = $newvalue;
174 1
                $this->informChanges();
175
            }
176
        } else {
177 1
            for ($i = count($result) - 1; $i >= 0; $i--) {
178 1
                if ($result[$i] == $oldvalue) {
179 1
                    $this->row[$fieldName][$i] = $newvalue;
180 1
                    $this->informChanges();
181
                }
182
            }
183
        }
184 1
    }
185
186
    /**
187
     * Get the \DOMElement row objet
188
     *
189
     * @return \DOMElement
190
     * @throws \ByJG\Util\Exception\XmlUtilException
191
     */
192 3
    public function getAsDom()
193
    {
194 3
        if (is_null($this->node)) {
195 3
            $this->node = XmlUtil::createXmlDocumentFromStr("<row></row>");
0 ignored issues
show
Documentation Bug introduced by
It seems like \ByJG\Util\XmlUtil::crea...tFromStr('<row></row>') of type object<DOMDocument> is incompatible with the declared type object<DOMElement> of property $node.

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...
196 3
            $root = $this->node->getElementsByTagName("row")->item(0);
197 3
            foreach ($this->row as $key => $value) {
198 3
                if (!is_array($value)) {
199 3
                    $field = XmlUtil::createChild($root, "field", $value);
200 3
                    XmlUtil::addAttribute($field, "name", $key);
201
                } else {
202 1
                    foreach ($value as $valueItem) {
203 1
                        $field = XmlUtil::createChild($root, "field", $valueItem);
204 3
                        XmlUtil::addAttribute($field, "name", $key);
205
                    }
206
                }
207
            }
208
        }
209 3
        return $this->node;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->node; of type DOMDocument|DOMElement adds the type DOMDocument to the return on line 209 which is incompatible with the return type documented by ByJG\AnyDataset\Core\Row::getAsDom of type DOMElement.
Loading history...
210
    }
211
212 18
    public function toArray()
213
    {
214 18
        return $this->row;
215
    }
216
217
    /**
218
     *
219
     * @return array
220
     */
221
    public function getAsJSON()
222
    {
223
        if (is_array($this->row)) {
224
            return json_decode(json_encode($this->row));
225
        } else {
226
            throw new UnexpectedValueException(
227
                'I expected that getRawFormat is array() but ' . gettype($this->row) . ' was given'
228
            );
229
        }
230
    }
231
232
    /**
233
     * @return array
234
     */
235 2
    public function getAsRaw()
236
    {
237 2
        return $this->originalRow;
238
    }
239
240
    /**
241
     *
242
     * @return bool
243
     */
244 1
    public function hasChanges()
245
    {
246 1
        return ($this->row != $this->originalRow);
247
    }
248
249
    /**
250
     *
251
     */
252 35
    public function acceptChanges()
253
    {
254 35
        $this->originalRow = $this->row;
255 35
    }
256
257
    /**
258
     *
259
     */
260 1
    public function rejectChanges()
261
    {
262 1
        $this->row = $this->originalRow;
263 1
    }
264
265 31
    protected function informChanges()
266
    {
267 31
        $this->node = null;
268 31
    }
269
270
    /**
271
     * Override Specific implementation of setPropValue to Row
272
     *
273
     * @param Row $obj
274
     * @param string $propName
275
     * @param string $value
276
     */
277 4
    protected function setPropValue($obj, $propName, $value)
278
    {
279 4
        $obj->set($propName, $value);
280 4
    }
281
}
282