ProductDetail::save()   F
last analyzed

Complexity

Conditions 23
Paths 1192

Size

Total Lines 122
Code Lines 70

Duplication

Lines 24
Ratio 19.67 %

Code Coverage

Tests 64
CRAP Score 27.232

Importance

Changes 0
Metric Value
cc 23
eloc 70
nc 1192
nop 1
dl 24
loc 122
rs 2
c 0
b 0
f 0
ccs 64
cts 80
cp 0.8
crap 27.232

How to fix   Long Method    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
 * Styrer varer
4
 *
5
 * @package Intraface_Product
6
 * @version 001
7
 * @author Lars Olesen <[email protected]>
8
 *
9
 * TODO Lige nu gemmer den altid en ny produktdetalje uanset, hvad jeg g�r.
10
 */
11
class ProductDetail extends Intraface_Standard
12
{
13
    /**
14
     * @var array
15
     */
16
    public $value = array();
17
18
    /**
19
     * @var array
20
     */
21
    private $fields; // tabelfelter
22
23
    /**
24
     * @var integer
25
     */
26
    private $detail_id;
27
28
    /**
29
     * @var integer
30
     */
31
    private $old_detail_id;
32
33
    /**
34
     * @var object
35
     */
36
    private $product;
37
38
    /**
39
     * @var object
40
     */
41
    private $db;
42
43
    /**
44
     * Constructor
45
     *
46
     * @param object  $product       Product object
47
     * @param integer $old_detail_id Only used with old product details
48
     *
49
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
50
     */
51 66
    public function __construct($product, $old_detail_id = 0)
52
    {
53 66
        $this->product       = $product;
54 66
        $this->db            = new DB_Sql;
55 66
        $this->old_detail_id = (int)$old_detail_id;
56 66
        $this->fields        = array('number', 'price', 'before_price', 'do_show', 'vat', 'weight', 'state_account_id');
57 66
        $this->detail_id     = $this->load();
58 66
    }
59
60
    function getNumber()
61
    {
62
        return $this->get('number');
63
    }
64
65
    /**
66
     * Loads details into an array
67
     *
68
     * @return integer product detail id on success or zero
69
     */
70 66
    private function load()
71
    {
72 66
        if ($this->old_detail_id != 0) {
73 15
            $sql = "product_detail.id = ".$this->old_detail_id;
74 15
        } else {
75 66
            $sql = "active = 1";
76
        }
77
78 66
        $sql = "SELECT product_detail.id, product_detail.unit AS unit_key,".implode(',', $this->fields).", product_detail_translation.name, product_detail_translation.description FROM product_detail
79
            LEFT JOIN product_detail_translation ON product_detail.id = product_detail_translation.id AND product_detail_translation.lang = 'da'
80 66
            WHERE ".$sql . "
81 66
            AND product_id = " . $this->product->get('id') . ' AND intranet_id = ' . $this->product->intranet->getId();
82 66
        $this->db->query($sql);
83 66
        if ($this->db->numRows() > 1) {
84
            throw new Exception('Der er mere end en aktiv produktdetalje');
85 66
        } elseif ($this->db->nextRecord()) {
86
            // hardcoded udtr�k af nogle vigtige oplysnigner, som vi ikke kan have i feltlisten
87 66 View Code Duplication
            for ($i = 0, $max = count($this->fields); $i<$max; $i++) {
88 66
                $this->value[$this->fields[$i]] = $this->db->f($this->fields[$i]);
89 66
            }
90 66
            $this->value['name'] = $this->db->f('name');
91 66
            $this->value['description'] = $this->db->f('description');
92 66
            $this->value['unit_key'] = $this->db->f('unit_key');
93
94
            // unit skal skrives om til den egentlige unit alt efter settings i produkterne
95 66
            $this->value['detail_id'] = $this->db->f('id');
96
97 66
            $unit = $this->getUnits($this->db->f('unit_key'));
98 66
            if (empty($unit)) {
99
                throw new Exception('invalid unit '.$this->db->f('unit_key').'!');
100
                exit;
0 ignored issues
show
Unused Code introduced by
die; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
Coding Style Compatibility introduced by
The method load() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
101
            }
102
103 66
            $this->value['unit_id']   = $this->db->f('unit_key');
104 66
            $this->value['unit']     = $unit;
105
106
            // udregne moms priser ud fra prisen, men kun hvis der er moms p� den
107 66
            if ($this->db->f('vat') == 1) {
108 64
                $this->value['vat_percent'] = 25;
109 64
                $this->value['price_incl_vat'] = round((float)$this->db->f('price') + ((float)$this->db->f('price') * 0.25), 2);
110 64
            } else {
111 2
                $this->value['vat_percent'] = 0;
112 2
                $this->value['price_incl_vat'] = round((float)$this->db->f('price'), 2);
113
            }
114 66
            return $this->db->f('id');
115
        } else {
116 66
            return 0;
117
        }
118
    }
119
120
    /**
121
     * Validates
122
     *
123
     * @param array $array_var Details to validate
124
     *
125
     * @return boolean
126
     */
127
    private function validate($array_var)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
128
    {
129
        $validator = new Intraface_Validator($this->product->error);
130
        $validator->isString($array_var['name'], 'Du har brugt ulovlige tegn i beskrivelsen');
131
        $validator->isString($array_var['description'], 'Du har brugt ulovlige tegn i beskrivelsen', '<strong><em>', 'allow_empty');
132
        $validator->isNumeric($array_var['unit'], 'Fejl i unit');
133
134
        $validator->isNumeric($array_var['state_account_id'], 'Fejl i state_account', 'allow_empty');
135
        $validator->isNumeric($array_var['do_show'], 'Fejl i do_show', 'allow_empty');
136
        $validator->isNumeric($array_var['vat'], 'Fejl i vat');
137
        $validator->isNumeric($array_var['pic_id'], 'Fejl i billedid', 'allow_empty');
138
        $validator->isNumeric($array_var['weight'], 'Fejl i vægt - skal være et helt tal', 'allow_empty');
139
140
        if (isset($array_var['price'])) {
141
            $validator->isNumeric($array_var['price'], 'Fejl i pris', 'allow_empty');
142
        }
143
        if (isset($array_var['before_price'])) {
144
            $validator->isNumeric($array_var['before_price'], 'Fejl i førpris', 'allow_empty');
145
        }
146
147
        if ($this->product->error->isError()) {
148
            return false;
149
        }
150
151
        return true;
152
    }
153
154
    /**
155
     * Saves data
156
     *
157
     * The old address is saved and deactivated, while the new details are activated. Data should never
158
     * be saved on an old product detail id.
159
     *
160
     * @param array $array_var An array with data to save, @see $this->fields
161
     *
162
     * @return integer
163
     */
164 66
    public function save($array_var)
165
    {
166 66
        $array_var = safeToDb($array_var);
167
168 66 View Code Duplication
        if (isset($array_var['price'])) {
169 66
            $amount = new Intraface_Amount($array_var['price']);
170 66
            $amount->convert2db();
171 66
            $array_var['price'] = $amount->get();
172 66
        }
173
174 66 View Code Duplication
        if (isset($array_var['before_price'])) {
175
            $amount = new Intraface_Amount($array_var['before_price']);
176
            $amount->convert2db();
177
            $array_var['before_price'] = $amount->get();
178
        }
179
180
181 66
        if ($this->old_detail_id != 0) {
182
            // save kan ikke bruges hvis man skal opdatere et gammelt produkt
183
            // men s� b�r den vel bare automatisk kalde update(), som i �jeblikket
184
            // er udkommenteret.
185
            return false;
186 66
        } elseif (count($array_var) == 0) {
187
            // Der er ikke noget indhold i arrayet
188
            return false;
189
        }
190
191
        // $this->db->query("SELECT * FROM product_detail WHERE id = ".$this->detail_id . "
192
        //         AND product_id = " . $this->product->get('id') . ' AND intranet_id = ' . $this->product->intranet->getId());
193
194 66
        if ($this->detail_id != 0) { // $this->db->nextRecord()
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
195
            // her skal vi s�rge for at f� billedet med
196 4
            $do_update = 0;
197 4
            $sql       = '';
198
199
            // check if there is any changes and only update changes.
200 4
            foreach ($this->fields as $field) {
201 4
                if (isset($array_var[$field])) {
202 4
                    if ($this->get($field) != $array_var[$field]) {
203 3
                        $do_update = 1;
204 3
                    }
205
206 4
                    $sql .= $field." = '".$array_var[$field]."', ";
207 4
                } else {
208 4
                    $sql .= $field." = '".$this->get($field)."', ";
209
                }
210 4
            }
211
212 4
            if (isset($array_var['unit'])) {
213 2
                if ($array_var['unit'] != $this->get('unit_key')) {
214
                    $do_update = 1;
215
                }
216 2
                $sql .= "unit = '".$array_var['unit']."', ";
217 2
            } else {
218 2
                $sql .= "unit = '".$this->get('unit_key')."', ";
219
            }
220
221 4 View Code Duplication
            if (isset($array_var['name'])) {
222 2
                if ($array_var['name'] != $this->get('name')) {
223 1
                    $do_update = 1;
224 1
                }
225 2
            } else {
226 2
                $array_var['name'] = $this->get('name');
227
            }
228
229 4 View Code Duplication
            if (isset($array_var['description'])) {
230
                if ($array_var['description'] != $this->get('description')) {
231
                    $do_update = 1;
232
                }
233
            } else {
234 4
                $array_var['description'] = $this->get('description');
235
            }
236 4
        } else {
237
            // der er ikke nogen tidligere poster, s� vi opdatere selvf�lgelig
238 66
            $do_update = 1;
239 66
            $sql       = '';
240
            // we make sure that unit is set to a valid unit.
241 66
            if (empty($array_var['unit'])) {
242 42
                $array_var['unit'] = 1;
243 42
            }
244 66
            $sql .= "unit = ".intval($array_var['unit']).", ";
245
246 66
            if (!isset($array_var['name'])) {
247
                $array_var['name'] = '';
248
            }
249 66
            if (!isset($array_var['description'])) {
250 66
                $array_var['description'] = '';
251 66
            }
252
253 66
            foreach ($this->fields as $field) {
254 66
                if (!array_key_exists($field, $array_var)) {
255 66
                    continue;
256
                }
257 66
                if (!empty($array_var[$field])) {
258 66
                    $sql .= $field." = '".$array_var[$field]."', ";
259 66
                } elseif (isset($array_var[$field])) {
260 3
                    $sql .= $field." = '', ";
261 3
                } else {
262
                    continue;
263
                }
264 66
            }
265
        }
266
267 66
        if ($do_update == 0) {
268
            // Hmmmmm, der er slet ikke nogen felter der er �ndret! S� gemmer vi ikke, men siger at det gik godt :-)
269
            return true;
270
        } else {
271
            // vi opdaterer produktet
272 66
            $this->db->query("UPDATE product_detail SET active = 0 WHERE product_id = " . $this->product->get('id'));
273 66
            $this->db->query("INSERT INTO product_detail SET ".$sql." active = 1, changed_date = NOW(), product_id = " . $this->product->get('id') . ", intranet_id = " . $this->product->intranet->getId());
274 66
            $this->detail_id = $this->db->insertedId();
275 66
            $this->db->query("INSERT INTO product_detail_translation SET name = \"".$array_var['name']."\", description = \"".$array_var['description']."\", lang = 'da', id = ".$this->detail_id);
276
277
278 66
            $this->load();
279 66
            $this->product->load();
280
281 66
            $this->old_detail_id = $this->detail_id;
282
283 66
            return true;
284
        }
285
    }
286
287 25
    public function getPrice()
288
    {
289 25
        return new Ilib_Variable_Float($this->get('price'));
290
    }
291
292 3
    public function getPriceInCurrency($currency, $exchange_rate_id = 0)
293
    {
294 3
        return new Ilib_Variable_Float(round($this->get('price') / ($currency->getProductPriceExchangeRate((int)$exchange_rate_id)->getRate()->getAsIso() / 100), 2), 'iso');
295
    }
296
297 10
    public function getPriceIncludingVat()
298
    {
299 10
        return new Ilib_Variable_Float(round($this->get('price') * (1 + $this->getVatPercent()->getAsIso()/100), 2));
300
    }
301
302
    public function getPriceIncludingVatInCurrency($currency, $exchange_rate_id = 0)
303
    {
304
        return new Ilib_Variable_Float(round($this->get('price') / ($currency->getProductPriceExchangeRate((int)$exchange_rate_id)->getRate()->getAsIso() / 100) * (1 + $this->getVatPercent()->getAsIso()/100), 2), 'iso');
305
    }
306
307 1
    public function getBeforePrice()
308
    {
309 1
        return new Ilib_Variable_Float($this->get('before_price'));
310
    }
311
312
    public function getBeforePriceInCurrency($currency, $exchange_rate_id = 0)
313
    {
314
        return new Ilib_Variable_Float(round($this->get('price') / ($currency->getProductPriceExchangeRate((int)$exchange_rate_id)->getRate()->getAsIso() / 100), 2), 'iso');
315
    }
316
317 1
    public function getBeforePriceIncludingVat()
318
    {
319 1
        return new Ilib_Variable_Float(round($this->get('before_price') * (1 + $this->getVatPercent()->getAsIso()/100), 2));
320
    }
321
322
    public function getBeforePriceIncludingVatInCurrency($currency, $exchange_rate_id = 0)
323
    {
324
        return new Ilib_Variable_Float(round($this->get('before_price') / ($currency->getProductPriceExchangeRate((int)$exchange_rate_id)->getRate()->getAsIso() / 100) * (1 + $this->getVatPercent()->getAsIso()/100), 2), 'iso');
325
    }
326
327 10
    public function getVatPercent()
328
    {
329 10
        return new Ilib_Variable_Float($this->value['vat_percent']);
330
    }
331
332
    /**
333
     * Gets the corresponding unit to a key
334
     *
335
     * @param string $key The unit key
336
     *
337
     * @return array
338
     */
339 66 View Code Duplication
    public static function getUnits($key = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
340
    {
341 66
        $units = array(1 => array('singular' => '',
342 66
                                  'plural' => '',
343 66
                                  'combined' => ''),
344 66
                       2 => array('singular' => 'unit',
345 66
                                  'plural' => 'units',
346 66
                                  'combined' => 'unit(s)'),
347 66
                       3 => array('singular' => 'day',
348 66
                                  'plural' => 'days',
349 66
                                  'combined' => 'day(s)'),
350 66
                       4 => array('singular' => 'month (singular)',
351 66
                                  'plural' => 'month (plural)',
352 66
                                  'combined' => 'month (combined)'),
353 66
                       5 => array('singular' => 'year',
354 66
                                  'plural' => 'years',
355 66
                                  'combined' => 'year(s)'),
356 66
                       6 => array('singular' => 'hour',
357 66
                                  'plural' => 'hours',
358 66
                                  'combined' => 'hour(s)')
359 66
                 );
360
361 66
        if ($key === null) {
362
            return $units;
363
        } else {
364 66
            if (!empty($units[$key])) {
365 66
                return $units[$key];
366
            } else {
367
                return '';
368
            }
369
        }
370
    }
371
372 1
    function setStateAccountId($id)
373
    {
374 1
        $db = new DB_Sql;
375 1
        $db->query('UPDATE product_detail SET state_account_id = ' . $id . ' WHERE id = ' . $this->detail_id);
376 1
        $this->load();
377 1
        $this->product->load();
378 1
        return true;
379
    }
380
}
381