Completed
Pull Request — 2.1 (#1090)
by Paweł
09:07
created

Article   F

Complexity

Total Complexity 65

Size/Duplication

Total Lines 405
Duplicated Lines 0 %

Coupling/Cohesion

Components 7
Dependencies 15

Importance

Changes 0
Metric Value
wmc 65
lcom 7
cbo 15
dl 0
loc 405
rs 3.2
c 0
b 0
f 0

48 Methods

Rating   Name   Duplication   Size   Complexity  
A setPublishStartDate() 0 4 1
A getCode() 0 4 1
A setCode() 0 4 1
A addSourceReference() 0 6 2
A removeSourceReference() 0 4 1
A hasSourceReference() 0 4 1
A getSources() 0 14 3
A getExtra() 0 4 1
A setExtra() 0 4 1
A getSlideshows() 0 4 1
A hasSlideshow() 0 4 1
A addSlideshow() 0 7 2
A removeSlideshow() 0 7 2
A isPublished() 0 4 1
A setRoute() 0 4 1
A getRoute() 0 4 1
A getId() 0 4 1
A getBody() 0 4 1
A setBody() 0 4 1
A getPublishStartDate() 0 4 1
A setPublishEndDate() 0 4 1
A getPublishEndDate() 0 4 1
A isPublishable() 0 4 1
A setPublishable() 0 4 1
A setIsPublishable() 0 4 1
A __construct() 0 12 1
A getTitle() 0 4 1
A getPlace() 0 10 4
A getPlaces() 0 10 4
A setTitle() 0 12 3
A getSlug() 0 4 1
A setSlug() 0 13 2
A getPublishedAt() 0 4 1
A setPublishedAt() 0 4 1
A getStatus() 0 4 1
A setStatus() 0 4 1
A getTemplateName() 0 4 1
A setTemplateName() 0 4 1
A getMetadata() 0 4 1
A getMetadataByKey() 0 8 2
A setMetadata() 0 4 1
A getSubjectType() 0 4 1
A getLead() 0 4 1
A setLead() 0 4 1
A getPreviousRelativeUrl() 0 4 1
A hasPreviousRelativeUrl() 0 4 1
A addPreviousRelativeUrl() 0 7 2
A removePreviousRelativeUrl() 0 7 2

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Content Bundle.
7
 *
8
 * Copyright 2016 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2016 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\ContentBundle\Model;
18
19
use Behat\Transliterator\Transliterator;
20
use Doctrine\Common\Collections\ArrayCollection;
21
use Doctrine\Common\Collections\Collection;
22
use SWP\Bundle\ContentBundle\Doctrine\ORM\TimestampableCancelTrait;
23
use SWP\Component\Bridge\Model\AuthorsAwareTrait;
24
use SWP\Component\Common\ArrayHelper;
25
use SWP\Component\Common\Model\DateTime;
26
use SWP\Component\Common\Model\SoftDeletableTrait;
27
use SWP\Component\Common\Model\TimestampableTrait;
28
use SWP\Component\Common\Model\TranslatableTrait;
29
use SWP\Component\Seo\Model\SeoMetadataAwareTrait;
30
31
class Article implements ArticleInterface
32
{
33
    use TranslatableTrait;
34
    use SoftDeletableTrait;
35
    use TimestampableTrait;
36
    use AuthorsAwareTrait;
37
    use KeywordsAwareTrait;
38
    use RelatedArticlesAwareTrait;
39
    use TimestampableCancelTrait;
40
    use SeoMetadataAwareTrait;
41
    use MediaAwareTrait;
42
43
    /**
44
     * @var mixed
45
     */
46
    protected $id;
47
48
    /**
49
     * @var string
50
     */
51
    protected $title;
52
53
    /**
54
     * @var string
55
     */
56
    protected $body;
57
58
    /**
59
     * @var string
60
     */
61
    protected $slug;
62
63
    /**
64
     * @var \DateTime
65
     */
66
    protected $publishedAt;
67
68
    /**
69
     * @var string
70
     */
71
    protected $status = ArticleInterface::STATUS_NEW;
72
73
    /**
74
     * @var RouteInterface
75
     */
76
    protected $route;
77
78
    /**
79
     * @var string
80
     */
81
    protected $templateName;
82
83
    /**
84
     * @var \DateTime
85
     */
86
    protected $publishStartDate;
87
88
    /**
89
     * @var \DateTime
90
     */
91
    protected $publishEndDate;
92
93
    /**
94
     * @var bool
95
     */
96
    protected $isPublishable;
97
98
    /**
99
     * @var array
100
     */
101
    protected $metadata = [];
102
103
    /**
104
     * @var string
105
     */
106
    protected $lead;
107
108
    /**
109
     * @var string
110
     */
111
    protected $code;
112
113
    /**
114
     * @var Collection|ArticleSourceInterface[]
115
     */
116
    protected $sources;
117
118
    /**
119
     * @var array|null
120
     */
121
    protected $extra;
122
123
    /**
124
     * @var Collection|SlideshowInterface[]
125
     */
126
    protected $slideshows;
127
128
    /** @var Collection|ArticlePreviousRelativeUrlInterface[] * */
129
    protected $previousRelativeUrls;
130
131
    public function __construct()
132
    {
133
        $this->createdAt = DateTime::getCurrentDateTime();
134
        $this->setPublishable(false);
135
        $this->setMedia(new ArrayCollection());
136
        $this->sources = new ArrayCollection();
137
        $this->authors = new ArrayCollection();
138
        $this->keywords = new ArrayCollection();
139
        $this->slideshows = new ArrayCollection();
140
        $this->relatedArticles = new ArrayCollection();
141
        $this->previousRelativeUrls = new ArrayCollection();
142
    }
143
144
    public function setPublishStartDate(\DateTime $startDate = null)
145
    {
146
        $this->publishStartDate = $startDate;
147
    }
148
149
    public function getPublishStartDate()
150
    {
151
        return $this->publishStartDate;
152
    }
153
154
    public function setPublishEndDate(\DateTime $endDate = null)
155
    {
156
        $this->publishEndDate = $endDate;
157
    }
158
159
    public function getPublishEndDate()
160
    {
161
        return $this->publishEndDate;
162
    }
163
164
    public function isPublishable()
165
    {
166
        return $this->isPublishable;
167
    }
168
169
    public function setPublishable($boolean)
170
    {
171
        $this->isPublishable = $boolean;
172
    }
173
174
    public function setIsPublishable(bool $boolean): void
175
    {
176
        $this->setPublishable($boolean);
177
    }
178
179
    public function isPublished()
180
    {
181
        return ArticleInterface::STATUS_PUBLISHED === $this->getStatus();
182
    }
183
184
    public function setRoute(RouteInterface $route = null)
185
    {
186
        $this->route = $route;
187
    }
188
189
    public function getRoute()
190
    {
191
        return $this->route;
192
    }
193
194
    public function getId()
195
    {
196
        return $this->id;
197
    }
198
199
    public function getBody()
200
    {
201
        return $this->body;
202
    }
203
204
    public function setBody($body)
205
    {
206
        $this->body = \trim($body);
207
    }
208
209
    public function getTitle()
210
    {
211
        return $this->title;
212
    }
213
214
    public function getPlace(): ?array
215
    {
216
        $metadata = $this->getMetadata();
217
218
        if (isset($metadata['place']) && is_array($metadata['place']) && count($metadata['place']) > 0) {
219
            return $metadata['place'][array_key_first($metadata['place'])];
220
        }
221
222
        return null;
223
    }
224
225
    public function getPlaces(): array
226
    {
227
        $metadata = $this->getMetadata();
228
229
        if (isset($metadata['place']) && is_array($metadata['place']) && count($metadata['place']) > 0) {
230
            return $metadata['place'];
231
        }
232
233
        return [];
234
    }
235
236
    public function setTitle($title)
237
    {
238
        $this->title = $title;
239
240
        if (null !== $this->slug && '' !== $this->slug) {
241
            $this->setSlug($this->slug);
242
243
            return;
244
        }
245
246
        $this->setSlug($this->title);
247
    }
248
249
    public function getSlug()
250
    {
251
        return $this->slug;
252
    }
253
254
    public function setSlug($slug)
255
    {
256
        $urlizedSlug = Transliterator::urlize($slug);
257
258
        if ('' === $urlizedSlug) {
259
            $slug = str_replace('\'', '-', $slug);
260
            $this->slug = Transliterator::transliterate($slug);
261
262
            return;
263
        }
264
265
        $this->slug = $urlizedSlug;
266
    }
267
268
    public function getPublishedAt()
269
    {
270
        return $this->publishedAt;
271
    }
272
273
    public function setPublishedAt(\DateTime $publishedAt)
274
    {
275
        $this->publishedAt = $publishedAt;
276
    }
277
278
    public function getStatus()
279
    {
280
        return $this->status;
281
    }
282
283
    public function setStatus($status)
284
    {
285
        $this->status = $status;
286
    }
287
288
    public function getTemplateName()
289
    {
290
        return $this->templateName;
291
    }
292
293
    public function setTemplateName($templateName)
294
    {
295
        $this->templateName = $templateName;
296
    }
297
298
    public function getMetadata()
299
    {
300
        return $this->metadata;
301
    }
302
303
    public function getMetadataByKey(string $key)
304
    {
305
        $metadata = $this->getMetadata();
306
307
        if (isset($metadata[$key])) {
308
            return $metadata[$key];
309
        }
310
    }
311
312
    public function setMetadata(array $metadata)
313
    {
314
        $this->metadata = ArrayHelper::sortNestedArrayAssocAlphabeticallyByKey($metadata);
315
    }
316
317
    public function getSubjectType()
318
    {
319
        return 'article';
320
    }
321
322
    public function getLead()
323
    {
324
        return $this->lead;
325
    }
326
327
    public function setLead($lead)
328
    {
329
        $this->lead = $lead;
330
    }
331
332
    public function getCode(): string
333
    {
334
        return $this->code;
335
    }
336
337
    public function setCode(string $code)
338
    {
339
        $this->code = $code;
340
    }
341
342
    public function addSourceReference(ArticleSourceReferenceInterface $source)
343
    {
344
        if (!$this->hasSourceReference($source)) {
345
            $this->sources->add($source);
346
        }
347
    }
348
349
    public function removeSourceReference(ArticleSourceReferenceInterface $source)
350
    {
351
        $this->sources->removeElement($source);
352
    }
353
354
    public function hasSourceReference(ArticleSourceReferenceInterface $source): bool
355
    {
356
        return $this->sources->contains($source);
357
    }
358
359
    public function getSources(): Collection
360
    {
361
        if (0 < $this->sources->count()) {
362
            $sources = new ArrayCollection();
363
            /** @var ArticleSourceReferenceInterface $source */
364
            foreach ($this->sources as $source) {
365
                $sources->add($source->getArticleSource());
366
            }
367
368
            return $sources;
369
        }
370
371
        return $this->sources;
372
    }
373
374
    public function getExtra(): ?array
375
    {
376
        return $this->extra;
377
    }
378
379
    public function setExtra(?array $extra): void
380
    {
381
        $this->extra = $extra;
382
    }
383
384
    public function getSlideshows(): Collection
385
    {
386
        return $this->slideshows;
387
    }
388
389
    public function hasSlideshow(SlideshowInterface $slideshow): bool
390
    {
391
        return $this->slideshows->contains($slideshow);
392
    }
393
394
    public function addSlideshow(SlideshowInterface $slideshow): void
395
    {
396
        if (!$this->hasSlideshow($slideshow)) {
397
            $slideshow->setArticle($this);
398
            $this->slideshows->add($slideshow);
399
        }
400
    }
401
402
    public function removeSlideshow(SlideshowInterface $slideshow): void
403
    {
404
        if ($this->hasSlideshow($slideshow)) {
405
            $slideshow->setArticle(null);
406
            $this->slideshows->removeElement($slideshow);
407
        }
408
    }
409
410
    public function getPreviousRelativeUrl(): Collection
411
    {
412
        return $this->previousRelativeUrls;
413
    }
414
415
    public function hasPreviousRelativeUrl(ArticlePreviousRelativeUrlInterface $previousRelativeUrl): bool
416
    {
417
        return $this->previousRelativeUrls->contains($previousRelativeUrl);
418
    }
419
420
    public function addPreviousRelativeUrl(ArticlePreviousRelativeUrlInterface $previousRelativeUrl): void
421
    {
422
        if (!$this->hasPreviousRelativeUrl($previousRelativeUrl)) {
423
            $previousRelativeUrl->setArticle($this);
424
            $this->previousRelativeUrls->add($previousRelativeUrl);
425
        }
426
    }
427
428
    public function removePreviousRelativeUrl(ArticlePreviousRelativeUrlInterface $previousRelativeUrl): void
429
    {
430
        if ($this->hasPreviousRelativeUrl($previousRelativeUrl)) {
431
            $previousRelativeUrl->setArticle(null);
432
            $this->previousRelativeUrls->removeElement($previousRelativeUrl);
433
        }
434
    }
435
}
436