Relational::getPrice()   B
last analyzed

Complexity

Conditions 8
Paths 8

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 5
Bugs 2 Features 2
Metric Value
c 5
b 2
f 2
dl 0
loc 21
ccs 0
cts 18
cp 0
rs 7.1428
cc 8
eloc 15
nc 8
nop 1
crap 72
1
<?php
2
3
namespace SpeckCatalog\Model\Product;
4
5
use SpeckCatalog\Model\AbstractModel;
6
use SpeckCatalog\Model\Product as Base;
7
8
class Relational extends Base
9
{
10
    protected $parent;
11
    protected $manufacturer;
12
    protected $options;
13
    protected $uoms;
14
    protected $images;
15
    protected $specs;
16
    protected $documents;
17
    protected $features;
18
    protected $builders;
19
20
    public function getKey()
21
    {
22
        return $this->productId;
23
    }
24
25
    public function getRecursivePrice($retailPrice = false)
26
    {
27
        $price = $this->getPrice($retailPrice);
28
29
        $adjustmentPrice = 0;
30
        if ($this->has('options')) {
31
            foreach ($this->getOptions() as $option) {
32
                $adjustmentPrice += $option->getRecursivePrice($price, $retailPrice);
33
            }
34
        }
35
36
        return $price + $adjustmentPrice;
37
    }
38
39
    public function type($type = null)
40
    {
41
        if ($type === 'shell') {
42
            $product->setProductTypeId(1);
0 ignored issues
show
Bug introduced by
The variable $product does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
43
        } elseif ($type === 'product') {
44
            $product->setProductTypeId(2);
45
        }
46
        switch ($this->getProductTypeId()) {
47
            case 1:
48
                return 'shell';
49
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
50
            case 2:
51
                return 'product';
52
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
53
        }
54
    }
55
56
57
    public function getPrice($retailPrice = false)
58
    {
59
        if ($this->has('uoms')) {
60
            $uomPrices = array();
61
            foreach ($this->getUoms() as $uom) {
62
                $uomPrices[] = $retailPrice ? $uom->getRetail() : $uom->getPrice();
63
            }
64
            asort($uomPrices, SORT_NUMERIC);
65
            return array_shift($uomPrices);
66
        } elseif ($this->has('builders')) {
67
            $uomPrices = array();
68
            foreach ($this->getBuilders() as $builder) {
69
                foreach ($builder->getProduct()->getUoms() as $uom) {
70
                    $uomPrices[] = $retailPrice ? $uom->getRetail() : $uom->getPrice();
71
                }
72
            }
73
            asort($uomPrices, SORT_NUMERIC);
74
            return array_shift($uomPrices);
75
        }
76
        return 0;
77
    }
78
79
    public function getImage()
80
    {
81
        if (isset($this->images[0])) {
82
            return $this->images[0];
83
        }
84
    }
85
86
    /**
87
     * @return uoms
88
     */
89
    public function getUoms()
90
    {
91
        return $this->uoms;
92
    }
93
94
    public function addUom($uom)
95
    {
96
        $uom->setParent($this);
97
        $this->uoms[] = $uom;
98
        return $this;
99
    }
100
101
    /**
102
     * @param $uoms
103
     * @return self
104
     */
105
    public function setUoms($uoms)
106
    {
107
        $this->uoms = array();
108
109
        foreach ($uoms as $uom) {
110
            $this->addUom($uom);
111
        }
112
113
        return $this;
114
    }
115
116
    /**
117
     * @return images
118
     */
119
    public function getImages()
120
    {
121
        return $this->images;
122
    }
123
124
    public function addImage($image)
125
    {
126
        $image->setParent($this);
127
        $this->images[] = $image;
128
        return $this;
129
    }
130
131
    /**
132
     * @param $images
133
     * @return self
134
     */
135
    public function setImages($images)
136
    {
137
        $this->images = array();
138
139
        foreach ($images as $image) {
140
            $this->addImage($image);
141
        }
142
143
        return $this;
144
    }
145
146
    /**
147
     * @return specs
148
     */
149
    public function getSpecs()
150
    {
151
        return $this->specs;
152
    }
153
154
    public function addSpec($spec)
155
    {
156
        $spec->setParent($this);
157
        $this->specs[] = $spec;
158
        return $this;
159
    }
160
161
    /**
162
     * @param $specs
163
     * @return self
164
     */
165
    public function setSpecs($specs)
166
    {
167
        $this->specs = array();
168
169
        foreach ($specs as $spec) {
170
            $this->addSpec($spec);
171
        }
172
173
        return $this;
174
    }
175
176
    /**
177
     * @return documents
178
     */
179
    public function getDocuments()
180
    {
181
        return $this->documents;
182
    }
183
184
    public function addDocument($document)
185
    {
186
        $document->setParent($this);
187
        $this->documents[] = $document;
188
        return $this;
189
    }
190
191
    /**
192
     * @param $documents
193
     * @return self
194
     */
195
    public function setDocuments($documents)
196
    {
197
        $this->documents = array();
198
199
        foreach ($documents as $document) {
200
            $this->addDocument($document);
201
        }
202
203
        return $this;
204
    }
205
206
    /**
207
     * @return features
208
     */
209
    public function getFeatures()
210
    {
211
        return $this->features;
212
    }
213
214
    public function addFeature($feature)
215
    {
216
        $feature->setParent($this);
217
        $this->features[] = $feature;
218
        return $this;
219
    }
220
221
    /**
222
     * @param $features
223
     * @return self
224
     */
225
    public function setFeatures($features)
226
    {
227
        $this->features = array();
228
229
        foreach ($features as $feature) {
230
            $this->addFeature($feature);
231
        }
232
233
        return $this;
234
    }
235
236
    /**
237
     * @return options
238
     */
239
    public function getOptions()
240
    {
241
        return $this->options;
242
    }
243
244
    public function addOption($option)
245
    {
246
        $option->setParent($this);
247
        $this->options[] = $option;
248
        return $this;
249
    }
250
251
    /**
252
     * @param $options
253
     * @return self
254
     */
255
    public function setOptions($options)
256
    {
257
        $this->options = array();
258
259
        foreach ($options as $option) {
260
            $this->addOption($option);
261
        }
262
263
        return $this;
264
    }
265
266
    /**
267
     * @return manufacturer
268
     */
269
    public function getManufacturer()
270
    {
271
        return $this->manufacturer;
272
    }
273
274
    /**
275
     * @param $manufacturer
276
     * @return self
277
     */
278
    public function setManufacturer(\SpeckContact\Entity\Company $manufacturer = null)
279
    {
280
        if ($manufacturer) {
281
            $manufacturer->setParent($this);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SpeckContact\Entity\Company as the method setParent() does only exist in the following sub-classes of SpeckContact\Entity\Company: SpeckCatalog\Model\Company\Relational. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
282
        }
283
        $this->manufacturer = $manufacturer;
284
        return $this;
285
    }
286
287
    public function __toString()
288
    {
289
        $name = $this->getName();
290
        $parent = parent::__toString();
291
        return ($name ?: $parent);
292
    }
293
294
    /**
295
     * @return parent
296
     */
297
    public function getParent()
298
    {
299
        return $this->parent;
300
    }
301
302
    /**
303
     * @param $parent
304
     * @return self
305
     */
306
    public function setParent(AbstractModel $parent)
307
    {
308
        $this->parent = $parent;
309
        return $this;
310
    }
311
312
    /**
313
     * @return builders
314
     */
315
    public function getBuilders()
316
    {
317
        return $this->builders;
318
    }
319
320
    /**
321
     * @param $builders
322
     * @return self
323
     */
324
    public function setBuilders($builders)
325
    {
326
        $this->builders = $builders;
327
        return $this;
328
    }
329
}
330