Passed
Push — master ( 971ccd...32a5d3 )
by Matthias
05:09
created

ObjectBase   C

Complexity

Total Complexity 77

Size/Duplication

Total Lines 361
Duplicated Lines 9.7 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 73.98%

Importance

Changes 0
Metric Value
wmc 77
lcom 1
cbo 4
dl 35
loc 361
ccs 145
cts 196
cp 0.7398
rs 5.4715
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
D assignProperties() 35 109 43
B handleImageAttribute() 0 21 6
B handleVideoAttribute() 0 18 5
A handleAudioAttribute() 0 12 3
A convertToDateTime() 0 4 1
A convertToBoolean() 0 11 3
F getProperties() 0 62 15

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ObjectBase 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 ObjectBase, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Fusonic\OpenGraph\Objects;
4
5
use Fusonic\Linq\Linq;
6
use Fusonic\OpenGraph\Elements\Audio;
7
use Fusonic\OpenGraph\Elements\Image;
8
use Fusonic\OpenGraph\Elements\Video;
9
use Fusonic\OpenGraph\Property;
10
11
/**
12
 * Abstract base class for all Open Graph objects (website, video, ...)
13
 */
14
abstract class ObjectBase
15
{
16
    /**
17
     * An array of audio resources attached to the object.
18
     *
19
     * @var array|Audio[]
20
     */
21
    public $audios = [];
22
23
    /**
24
     * A short description of the object.
25
     *
26
     * @var string
27
     */
28
    public $description;
29
30
    /**
31
     * The word that appears before the object's title in a sentence. This is an list of words from 'a', 'an', 'the',
32
     * ' "" ', or 'auto'. If 'auto' is chosen, the consumer of the object will chose between 'a' or 'an'. The default is
33
     * the blank, "".
34
     *
35
     * @var string
36
     */
37
    public $determiner;
38
39
    /**
40
     * An array of images attached to the object.
41
     *
42
     * @var array|Image[]
43
     */
44
    public $images = [];
45
46
    /**
47
     * The locale that the object's tags are marked up in, in the format language_TERRITORY.
48
     *
49
     * @var string
50
     */
51
    public $locale;
52
53
    /**
54
     * An array of alternate locales in which the resource is available.
55
     *
56
     * @var array|string[]
57
     */
58
    public $localeAlternate = [];
59
60
    /**
61
     * @var bool
62
     */
63
    public $richAttachment;
64
65
    /**
66
     * An array of URLs of related resources.
67
     *
68
     * @var array|string[]
69
     */
70
    public $seeAlso = [];
71
72
    /**
73
     * The name of the web site upon which the object resides.
74
     *
75
     * @var string
76
     */
77
    public $siteName;
78
79
    /**
80
     * The title of the object as it should appear in the graph.
81
     *
82
     * @var string
83
     */
84
    public $title;
85
86
    /**
87
     * The type of the object, such as 'article'.
88
     *
89
     * @var string
90
     */
91
    public $type;
92
93
    /**
94
     * The time when the object was last updated.
95
     *
96
     * @var \DateTime
97
     */
98
    public $updatedTime;
99
100
    /**
101
     * The canonical URL of the object, used as its ID in the graph.
102
     *
103
     * @var string
104
     */
105
    public $url;
106
107
    /**
108
     * An array of videos attached to the object.
109
     *
110
     * @var array|Video[]
111
     */
112
    public $videos = [];
113
114 27
    public function __construct()
115
    {
116 27
    }
117
118
    /**
119
     * Assigns all properties given to the this Object instance.
120
     *
121
     * @param   array|Property[]    $properties     Array of all properties to assign.
122
     * @param   bool                $debug          Throw exceptions when parsing or not.
123
     *
124
     * @throws  \UnexpectedValueException
125
     */
126 15
    public function assignProperties(array $properties, $debug = false)
127
    {
128 15
        foreach ($properties as $property) {
129 13
            $name = $property->key;
130 13
            $value = $property->value;
131
132
            switch($name) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after SWITCH keyword; 0 found
Loading history...
133 13
                case Property::AUDIO:
134 13
                case Property::AUDIO_URL:
135 1
                    $this->audios[] = new Audio($value);
136 1
                    break;
137 13
                case Property::AUDIO_SECURE_URL:
138 13 View Code Duplication
                case Property::AUDIO_TYPE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
139 3
                    if (count($this->audios) > 0) {
140 1
                        $this->handleAudioAttribute($this->audios[count($this->audios) - 1], $name, $value);
141 3
                    } elseif ($debug) {
142 1
                        throw new \UnexpectedValueException(
143 1
                            sprintf(
144 1
                                "Found '%s' property but no audio was found before.",
145
                                $name
146 1
                            )
147 1
                        );
148
                    }
149 2
                    break;
150 10
                case Property::DESCRIPTION:
151 1
                    if ($this->description === null) {
152 1
                        $this->description = $value;
153 1
                    }
154 1
                    break;
155 10
                case Property::DETERMINER:
156 1
                    if ($this->determiner === null) {
157 1
                        $this->determiner = $value;
158 1
                    }
159 1
                    break;
160 10
                case Property::IMAGE:
161 10
                case Property::IMAGE_URL:
162 2
                    $this->images[] = new Image($value);
163 2
                    break;
164 10
                case Property::IMAGE_HEIGHT:
165 10
                case Property::IMAGE_SECURE_URL:
166 10
                case Property::IMAGE_TYPE:
167 10
                case Property::IMAGE_WIDTH:
168 10 View Code Duplication
                case Property::IMAGE_USER_GENERATED:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
169 4
                    if (count($this->images) > 0) {
170 2
                        $this->handleImageAttribute($this->images[count($this->images) - 1], $name, $value);
171 4
                    } elseif ($debug) {
172 1
                        throw new \UnexpectedValueException(
173 1
                            sprintf(
174 1
                                "Found '%s' property but no image was found before.",
175
                                $name
176 1
                            )
177 1
                        );
178
                    }
179 3
                    break;
180 6
                case Property::LOCALE:
181 1
                    if ($this->locale === null) {
182 1
                        $this->locale = $value;
183 1
                    }
184 1
                    break;
185 6
                case Property::LOCALE_ALTERNATE:
186 1
                    $this->localeAlternate[] = $value;
187 1
                    break;
188 6
                case Property::RICH_ATTACHMENT:
189 1
                    $this->richAttachment = $this->convertToBoolean($value);
190 1
                    break;
191 6
                case Property::SEE_ALSO:
192 1
                    $this->seeAlso[] = $value;
193 1
                    break;
194 6
                case Property::SITE_NAME:
195 1
                    if ($this->siteName === null) {
196 1
                        $this->siteName = $value;
197 1
                    }
198 1
                    break;
199 6
                case Property::TITLE:
200 3
                    if ($this->title === null) {
201 3
                        $this->title = $value;
202 3
                    }
203 3
                    break;
204 4
                case Property::UPDATED_TIME:
205 1
                    if ($this->updatedTime === null && strtotime($value) !== false) {
206 1
                        $this->updatedTime = $this->convertToDateTime($value);
207 1
                    }
208 1
                    break;
209 4
                case Property::URL:
210 1
                    if ($this->url === null) {
211 1
                        $this->url = $value;
212 1
                    }
213 1
                    break;
214 3
                case Property::VIDEO:
215 3
                case Property::VIDEO_URL:
216 1
                    $this->videos[] = new Video($value);
217 1
                    break;
218 3
                case Property::VIDEO_HEIGHT:
219 3
                case Property::VIDEO_SECURE_URL:
220 3
                case Property::VIDEO_TYPE:
221 3 View Code Duplication
                case Property::VIDEO_WIDTH:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
222 3
                    if (count($this->videos) > 0) {
223 1
                        $this->handleVideoAttribute($this->videos[count($this->videos) - 1], $name, $value);
224 3
                    } elseif ($debug) {
225 1
                        throw new \UnexpectedValueException(
226 1
                            sprintf(
227 1
                                "Found '%s' property but no video was found before.",
228
                                $name
229 1
                            )
230 1
                        );
231
                    }
232 2
            }
233 12
        }
234 12
    }
235
236 2
    private function handleImageAttribute(Image $element, $name, $value)
237
    {
238
        switch($name)
0 ignored issues
show
Coding Style introduced by
Expected 1 space after SWITCH keyword; 0 found
Loading history...
239
        {
240 2
            case Property::IMAGE_HEIGHT:
241 2
                $element->height = (int)$value;
242 2
                break;
243 2
            case Property::IMAGE_WIDTH:
244 2
                $element->width = (int)$value;
245 2
                break;
246 1
            case Property::IMAGE_TYPE:
247 1
                $element->type = $value;
248 1
                break;
249 1
            case Property::IMAGE_SECURE_URL:
250 1
                $element->secureUrl = $value;
251 1
                break;
252
            case Property::IMAGE_USER_GENERATED:
253
                $element->userGenerated = $this->convertToBoolean($value);
254
                break;
255
        }
256 2
    }
257
258 1
    private function handleVideoAttribute(Video $element, $name, $value)
259
    {
260
        switch($name)
0 ignored issues
show
Coding Style introduced by
Expected 1 space after SWITCH keyword; 0 found
Loading history...
261
        {
262 1
            case Property::VIDEO_HEIGHT:
263 1
                $element->height = (int)$value;
264 1
                break;
265 1
            case Property::VIDEO_WIDTH:
266 1
                $element->width = (int)$value;
267 1
                break;
268 1
            case Property::VIDEO_TYPE:
269 1
                $element->type = $value;
270 1
                break;
271 1
            case Property::VIDEO_SECURE_URL:
272 1
                $element->secureUrl = $value;
273 1
                break;
274
        }
275 1
    }
276
277 1
    private function handleAudioAttribute(Audio $element, $name, $value)
278
    {
279
        switch($name)
0 ignored issues
show
Coding Style introduced by
Expected 1 space after SWITCH keyword; 0 found
Loading history...
280
        {
281 1
            case Property::AUDIO_TYPE:
282 1
                $element->type = $value;
283 1
                break;
284 1
            case Property::AUDIO_SECURE_URL:
285 1
                $element->secureUrl = $value;
286 1
                break;
287
        }
288 1
    }
289
290 1
    protected function convertToDateTime($value)
291
    {
292 1
        return new \DateTime($value);
293
    }
294
295 1
    protected function convertToBoolean($value)
296
    {
297 1
        switch(strtolower($value))
0 ignored issues
show
Coding Style introduced by
Expected 1 space after SWITCH keyword; 0 found
Loading history...
298
        {
299 1
            case "1":
300 1
            case "true":
301 1
                return true;
302
            default:
303
                return false;
304
        }
305
    }
306
307
    /**
308
     * Gets all properties set on this object.
309
     *
310
     * @return  array|Property[]
311
     */
312
    public function getProperties()
313
    {
314
        $properties = [];
315
316
        foreach ($this->audios as $audio) {
317
            $properties = array_merge($properties, $audio->getProperties());
318
        }
319
        
320
        if ($this->title !== null) {
321
            $properties[] = new Property(Property::TITLE, $this->title);
322
        }
323
324
        if ($this->description !== null) {
325
            $properties[] = new Property(Property::DESCRIPTION, $this->description);
326
        }
327
328
        if ($this->determiner !== null) {
329
            $properties[] = new Property(Property::DETERMINER, $this->determiner);
330
        }
331
332
        foreach ($this->images as $image) {
333
            $properties = array_merge($properties, $image->getProperties());
334
        }
335
336
        if ($this->locale !== null) {
337
            $properties[] = new Property(Property::LOCALE, $this->locale);
338
        }
339
340
        foreach ($this->localeAlternate as $locale) {
341
            $properties[] = new Property(Property::LOCALE_ALTERNATE, $locale);
342
        }
343
344
        if ($this->richAttachment !== null) {
345
            $properties[] = new Property(Property::RICH_ATTACHMENT, (int)$this->richAttachment);
346
        }
347
348
        foreach ($this->seeAlso as $seeAlso) {
349
            $properties[] = new Property(Property::SEE_ALSO, $seeAlso);
350
        }
351
352
        if ($this->siteName !== null) {
353
            $properties[] = new Property(Property::SITE_NAME, $this->siteName);
354
        }
355
356
        if ($this->type !== null) {
357
            $properties[] = new Property(Property::TYPE, $this->type);
358
        }
359
360
        if ($this->updatedTime !== null) {
361
            $properties[] = new Property(Property::UPDATED_TIME, $this->updatedTime->format("c"));
362
        }
363
364
        if ($this->url !== null) {
365
            $properties[] = new Property(Property::URL, $this->url);
366
        }
367
368
        foreach ($this->videos as $video) {
369
            $properties = array_merge($properties, $video->getProperties());
370
        }
371
372
        return $properties;
373
    }
374
}
375