Passed
Push — master ( 0ffa51...bdfaa4 )
by Radosław
02:21
created

Field::fromArray()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 12
cts 12
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 4
nop 1
crap 4
1
<?php
2
3
namespace Radowoj\Yaah;
4
5
/**
6
 * Class representation of WebAPI auction field
7
 */
8
class Field
9
{
10
    const VALUE_STRING = 'fvalueString';
11
    const VALUE_INT = 'fvalueInt';
12
    const VALUE_FLOAT = 'fvalueFloat';
13
    const VALUE_IMAGE = 'fvalueImage';
14
    const VALUE_DATETIME = 'fvalueDatetime';
15
    const VALUE_DATE = 'fvalueDate';
16
    const VALUE_RANGE_INT = 'fvalueRangeInt';
17
    const VALUE_RANGE_FLOAT = 'fvalueRangeFloat';
18
    const VALUE_RANGE_DATE = 'fvalueRangeDate';
19
20
    const DEFAULT_STRING = '';
21
    const DEFAULT_INT = 0;
22
    const DEFAULT_FLOAT = 0;
23
    const DEFAULT_IMAGE = '';
24
    const DEFAULT_DATETIME = 0;
25
    const DEFAULT_DATE = '';
26
27
    /**
28
     * Allegro WebAPI fid
29
     * @var integer
30
     */
31
    protected $fid = null;
32
33
34
    /**
35
     * array of fValues of this Field
36
     * @var array
37
     */
38
    protected $fValues = [];
39
40
41
    /**
42
     * @param integer $fid WebAPI fid for given field
43
     * @param mixed $value value for given field
44
     * @param string $forceValueType value type to force (i.e. fvalueImage)
45
     */
46 21
    public function __construct($fid = 0, $value = null, $forceValueType = '')
47
    {
48 21
        $this->setFid($fid);
49 20
        $this->fValues = $this->getDefaults();
50
51
        //null value should result in field with default values
52 20
        if (is_null($value)) {
53 7
            return;
54
        }
55
56
        //if value type was specified (useful for fvalueImage, fvalueDatetime etc.)
57 13
        if ($forceValueType) {
58 2
            $this->setValueForced($forceValueType, $value);
59 1
            return;
60
        }
61
62
        //if no forced value type is given, autodetect it
63 11
        $this->setValueAutodetect($value);
64 9
    }
65
66
67
    /**
68
     * Default values, "empty" WebAPI fields item
69
     * @return array
70
     */
71 20
    protected function getDefaults()
72
    {
73
        return [
74 20
            self::VALUE_STRING => self::DEFAULT_STRING,
75 20
            self::VALUE_INT => self::DEFAULT_INT,
76 20
            self::VALUE_FLOAT => self::DEFAULT_FLOAT,
77 20
            self::VALUE_IMAGE => self::DEFAULT_IMAGE,
78 20
            self::VALUE_DATETIME => self::DEFAULT_DATETIME,
79 20
            self::VALUE_DATE => self::DEFAULT_DATE,
80 20
            self::VALUE_RANGE_INT => [
81 20
                self::VALUE_RANGE_INT . 'Min' => self::DEFAULT_INT,
82 20
                self::VALUE_RANGE_INT . 'Max' => self::DEFAULT_INT,
83 20
            ],
84 20
            self::VALUE_RANGE_FLOAT => [
85 20
                self::VALUE_RANGE_FLOAT . 'Min' => self::DEFAULT_FLOAT,
86 20
                self::VALUE_RANGE_FLOAT . 'Max' => self::DEFAULT_FLOAT,
87 20
            ],
88 20
            self::VALUE_RANGE_DATE => [
89 20
                self::VALUE_RANGE_DATE . 'Min' => self::DEFAULT_DATE,
90 20
                self::VALUE_RANGE_DATE . 'Max' => self::DEFAULT_DATE,
91 20
            ],
92 20
        ];
93
    }
94
95
96
    /**
97
     * Set fid of this Field
98
     * @param integer $fid
99
     */
100 21
    public function setFid($fid)
101
    {
102 21
        if (!is_integer($fid)) {
103 1
            throw new Exception('fid must be an integer, ' . gettype($fid) . ' given');
104
        }
105 20
        $this->fid = $fid;
106 20
    }
107
108
109
    /**
110
     * Set value to fValue index of corresponding type
111
     * @param mixed $value
112
     */
113 11
    protected function setValueAutodetect($value)
114
    {
115 11
        if (is_integer($value)) {
116 2
            $this->fValues[self::VALUE_INT] = $value;
117 11
        } elseif (is_float($value)) {
118 2
            $this->fValues[self::VALUE_FLOAT] = $value;
119 10
        } elseif (is_string($value)) {
120 5
            $this->setValueStringAutodetect($value);
121 9
        } elseif (is_array($value)) {
122 3
            $this->setValueRangeAutodetect($value);
123 2
        } else {
124 1
            throw new Exception('Not supported value type: ' . gettype($value) . "; fid={$this->fid}");
125
        }
126 9
    }
127
128
129
    /**
130
     * Detect type of string value (date or normal string)
131
     * @param string $value value to detect type
132
     */
133 5
    protected function setValueStringAutodetect($value)
134
    {
135 5
        if (preg_match('/^\d{2}\-\d{2}\-\d{4}$/', $value)) {
136 2
            $this->fValues[self::VALUE_DATE] = $value;
137 2
        } else {
138 4
            $this->fValues[self::VALUE_STRING] = $value;
139
        }
140 5
    }
141
142
143
    /**
144
     * Detect type of range passed as argument (int, float, date)
145
     * @param array $value value to detect type of
0 ignored issues
show
Bug introduced by
There is no parameter named $value. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
146
     */
147 3
    protected function setValueRangeAutodetect(array $range)
148
    {
149 3
        if (count($range) !== 2) {
150 1
            throw new Exception('Range array must have exactly 2 elements');
151
        }
152
153
        //make sure array has numeric keys
154 2
        $range = array_values($range);
155
156 2
        asort($range);
157
158 2
        if ($this->isRangeFloat($range)) {
159 1
            $this->fValues[self::VALUE_RANGE_FLOAT] = array_combine(
160 1
                ['fvalueRangeFloatMin', 'fvalueRangeFloatMax'],
161
                $range
162 1
            );
163 2
        } elseif ($this->isRangeInt($range)) {
164 1
            $this->fValues[self::VALUE_RANGE_INT] = array_combine(
165 1
                ['fvalueRangeIntMin', 'fvalueRangeIntMax'],
166
                $range
167 1
            );
168 1
        }
169 2
    }
170
171
172
    /**
173
     * Checks if given range is float
174
     * @param  array   $range range to check
175
     * @return boolean
176
     */
177 2
    protected function isRangeFloat(array $range)
178
    {
179 2
        $floats = array_filter($range, 'is_float');
180 2
        return (count($floats) == 2);
181
    }
182
183
184
    /**
185
     * Checks if given range is int
186
     * @param  array   $range range to check
187
     * @return boolean
188
     */
189 1
    protected function isRangeInt(array $range)
190
    {
191 1
        $ints = array_filter($range, 'is_int');
192 1
        return (count($ints) == 2);
193
    }
194
195
196
    /**
197
     * Set value of arbitrary type
198
     * @param string $forceValueType type ('fvalueString', 'fvalueInt', ...)
199
     * @param mixed $value to set
200
     */
201 2
    protected function setValueForced($forceValueType, $value)
202
    {
203 2
        if (!array_key_exists($forceValueType, $this->fValues)) {
204 1
            throw new Exception("Class " . get_class($this) . " does not have property: {$forceValueType}");
205
        }
206
207 1
        $this->fValues[$forceValueType] = $value;
208 1
    }
209
210
211
    /**
212
     * Returns WebAPI representation of Field
213
     * @return array field
214
     */
215 9
    public function toArray()
216
    {
217 9
        $this->fValues['fid'] = $this->fid;
218 9
        return $this->fValues;
219
    }
220
221
222
    /**
223
     * Creates object from WebAPI representation of Field
224
     */
225 7
    public function fromArray(array $array)
226
    {
227
        //recursive object to array :)
228 7
        $array = json_decode(json_encode($array), true);
229
230 7
        if (!array_key_exists('fid', $array)) {
231 1
            throw new Exception('Fid is required');
232
        }
233
234 6
        $this->setFid($array['fid']);
235 6
        unset($array['fid']);
236
237 6
        foreach ($array as $key => $value) {
238 6
            if (!array_key_exists($key, $this->fValues)) {
239 1
                throw new Exception("Unknown Field property: {$key}");
240
            }
241
242 6
            $this->fValues[$key] = $value;
243 6
        }
244 5
    }
245
246
    /**
247
     * Return field fid
248
     * @return integer
249
     */
250 5
    public function getFid()
251
    {
252 5
        return $this->fid;
253
    }
254
255
256
    /**
257
     * Return first property that is different from its default value
258
     * @return mixed | null
259
     */
260 12
    public function getValue()
261
    {
262 12
        $defaults = $this->getDefaults();
263 12
        foreach ($this->fValues as $key => $fValue) {
264 12
            if ($fValue !== $defaults[$key]) {
265 11
                return is_array($fValue) ? array_values($fValue) : $fValue;
266
            }
267 10
        }
268
269
        //if all values are at defaults, we're unable to determine
270
        //which one was set without additional business logic involving
271
        //fids - especially if the defaults come from WebAPI (fromArray())
272 1
        return null;
273
    }
274
275
276
}
277