Passed
Push — master ( d093e3...81fa39 )
by Dāvis
03:13 queued 25s
created

Sitemap   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 185
rs 8.3396
c 1
b 0
f 0
wmc 44

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getSitemapIndexFilename() 0 14 2
A addSitemapIndex() 0 13 3
A getCurrentSitemapIndex() 0 3 1
A setDumper() 0 5 1
A addProvider() 0 5 1
B __construct() 0 13 7
B build() 0 30 6
A needHost() 0 7 2
A createSitemapIndex() 0 6 1
C add() 0 54 17
A isSitemapIndexable() 0 3 3

How to fix   Complexity   

Complex Class

Complex classes like Sitemap 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.

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 Sitemap, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Sludio\HelperBundle\Sitemap;
4
5
use Sludio\HelperBundle\Sitemap\Dumper\DumperInterface;
6
use Sludio\HelperBundle\Sitemap\Dumper\DumperFileInterface;
7
use Sludio\HelperBundle\Sitemap\Entity\Url;
8
use Sludio\HelperBundle\Sitemap\Entity\SitemapIndex;
9
use Sludio\HelperBundle\Sitemap\Formatter\FormatterInterface;
10
use Sludio\HelperBundle\Sitemap\Formatter\SitemapIndexFormatterInterface;
11
use Sludio\HelperBundle\Sitemap\Provider\ProviderInterface;
12
use Symfony\Component\HttpFoundation\RequestStack;
13
14
15
class Sitemap
16
{
17
    protected $providers = [];
18
    protected $dumper;
19
    protected $formatter;
20
    protected $baseHost;
21
    protected $limit = 0;
22
    protected $sitemapIndexes = [];
23
    protected $originalFilename;
24
25
    public function __construct(DumperInterface $dumper, FormatterInterface $formatter, $baseHost = null, $limit = 0, RequestStack $requestStack)
26
    {
27
        $this->dumper = $dumper;
28
        $this->formatter = $formatter;
29
        $this->baseHost = $baseHost;
30
        if ($this->baseHost === null && PHP_SAPI !== 'cli') {
31
            $request = $requestStack->getCurrentRequest();
32
            $useHttps = $request->server->get('HTTPS') || ($request->server->get('HTTP_X_FORWARDED_PROTO') && $request->server->get('HTTP_X_FORWARDED_PROTO') == 'https');
33
            $this->baseHost = ($useHttps ? 'https' : 'http').'://'.$request->server->get('HTTP_HOST');
34
        }
35
        $this->limit = $limit;
36
        if ($this->isSitemapIndexable()) {
37
            $this->originalFilename = $dumper->getFilename();
0 ignored issues
show
Bug introduced by
The method getFilename() does not exist on Sludio\HelperBundle\Sitemap\Dumper\DumperInterface. It seems like you code against a sub-type of Sludio\HelperBundle\Sitemap\Dumper\DumperInterface such as Sludio\HelperBundle\Site...per\DumperFileInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
            /** @scrutinizer ignore-call */ 
38
            $this->originalFilename = $dumper->getFilename();
Loading history...
38
        }
39
    }
40
41
    public function addProvider(ProviderInterface $provider)
42
    {
43
        $this->providers[] = $provider;
44
45
        return $this;
46
    }
47
48
    public function setDumper(DumperInterface $dumper)
49
    {
50
        $this->dumper = $dumper;
51
52
        return $this;
53
    }
54
55
    public function build()
56
    {
57
        if ($this->isSitemapIndexable()) {
58
            $this->addSitemapIndex($this->createSitemapIndex());
59
        }
60
61
        $this->dumper->dump($this->formatter->getSitemapStart());
62
63
        foreach ($this->providers as $provider) {
64
            $provider->populate($this);
65
        }
66
67
        $sitemapContent = $this->dumper->dump($this->formatter->getSitemapEnd());
68
69
        if (!$this->isSitemapIndexable()) {
70
            return $sitemapContent;
71
        }
72
73
        if (count($this->sitemapIndexes)) {
74
            $this->dumper->setFilename($this->originalFilename);
75
76
            $this->dumper->dump($this->formatter->getSitemapIndexStart());
77
            foreach ($this->sitemapIndexes as $sitemapIndex) {
78
                $this->dumper->dump($this->formatter->formatSitemapIndex($sitemapIndex));
79
            }
80
81
            $this->dumper->dump($this->formatter->getSitemapIndexEnd());
82
        }
83
84
        return null;
85
    }
86
87
    public function add(Url $url)
88
    {
89
        if ($this->isSitemapIndexable() && $this->getCurrentSitemapIndex()->getUrlCount() >= $this->limit) {
90
            $this->addSitemapIndex($this->createSitemapIndex());
91
        }
92
93
        $loc = $url->getLoc();
94
        if (empty($loc)) {
95
            throw new \InvalidArgumentException('The url MUST have a loc attribute');
96
        }
97
98
        if ($this->baseHost !== null) {
99
            if ($this->needHost($loc)) {
100
                $url->setLoc($this->baseHost.$loc);
101
            }
102
103
            foreach ($url->getVideos() as $video) {
104
                if ($this->needHost($video->getThumbnailLoc())) {
105
                    $video->setThumbnailLoc($this->baseHost.$video->getThumbnailLoc());
106
                }
107
108
                if ($this->needHost($video->getContentLoc())) {
109
                    $video->setContentLoc($this->baseHost.$video->getContentLoc());
110
                }
111
112
                $player = $video->getPlayerLoc();
113
                if ($player !== null && $this->needHost($player['loc'])) {
114
                    $video->setPlayerLoc($this->baseHost.$player['loc'], $player['allow_embed'], $player['autoplay']);
115
                }
116
117
                $gallery = $video->getGalleryLoc();
118
                if ($gallery !== null && $this->needHost($gallery['loc'])) {
119
                    $video->setGalleryLoc($this->baseHost.$gallery['loc'], $gallery['title']);
120
                }
121
            }
122
123
            foreach ($url->getImages() as $image) {
124
                if ($this->needHost($image->getLoc())) {
125
                    $image->setLoc($this->baseHost.$image->getLoc());
126
                }
127
128
                if ($this->needHost($image->getLicense())) {
129
                    $image->setLicense($this->baseHost.$image->getLicense());
130
                }
131
            }
132
        }
133
134
        $this->dumper->dump($this->formatter->formatUrl($url));
135
136
        if ($this->isSitemapIndexable()) {
137
            $this->getCurrentSitemapIndex()->incrementUrl();
138
        }
139
140
        return $this;
141
    }
142
143
    protected function needHost($url)
144
    {
145
        if ($url === null) {
146
            return false;
147
        }
148
149
        return 0 !== strpos($url, 'http');
150
    }
151
152
    protected function isSitemapIndexable()
153
    {
154
        return ($this->limit > 0 && $this->dumper instanceof DumperFileInterface && $this->formatter instanceof SitemapIndexFormatterInterface);
155
    }
156
157
    protected function createSitemapIndex()
158
    {
159
        $sitemapIndex = new SitemapIndex();
160
        $sitemapIndex->setLastmod(new \DateTime());
161
162
        return $sitemapIndex;
163
    }
164
165
    protected function addSitemapIndex(SitemapIndex $sitemapIndex)
166
    {
167
        $nbSitemapIndexs = count($this->sitemapIndexes);
168
169
        if ($nbSitemapIndexs > 0) {
170
            $this->dumper->dump($this->formatter->getSitemapEnd());
171
        }
172
        $sitemapIndexFilename = $this->getSitemapIndexFilename($this->originalFilename);
173
        $this->dumper->setFilename($sitemapIndexFilename);
0 ignored issues
show
Bug introduced by
The method setFilename() does not exist on Sludio\HelperBundle\Sitemap\Dumper\DumperInterface. It seems like you code against a sub-type of Sludio\HelperBundle\Sitemap\Dumper\DumperInterface such as Sludio\HelperBundle\Site...per\DumperFileInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

173
        $this->dumper->/** @scrutinizer ignore-call */ 
174
                       setFilename($sitemapIndexFilename);
Loading history...
174
175
        $this->sitemapIndexes[] = $sitemapIndex;
176
        if ($nbSitemapIndexs > 0) {
177
            $this->dumper->dump($this->formatter->getSitemapStart());
178
        }
179
    }
180
181
    protected function getCurrentSitemapIndex()
182
    {
183
        return end($this->sitemapIndexes);
184
    }
185
186
    protected function getSitemapIndexFilename($filename)
187
    {
188
        $sitemapIndexFilename = basename($filename);
189
        $index = count($this->sitemapIndexes) + 1;
190
        $extPosition = strrpos($sitemapIndexFilename, '.');
191
        if ($extPosition !== false) {
192
            $sitemapIndexFilename = substr($sitemapIndexFilename, 0, $extPosition).'-'.$index.substr($sitemapIndexFilename, $extPosition);
193
        } else {
194
            $sitemapIndexFilename .= '-'.$index;
195
        }
196
197
        $sitemapIndexFilename = dirname($filename).DIRECTORY_SEPARATOR.$sitemapIndexFilename;
198
199
        return $sitemapIndexFilename;
200
    }
201
}
202