Passed
Push — ft/sitemap ( 686bce...8c914b )
by Ben
07:09
created

SitemapXml   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
eloc 28
c 1
b 0
f 0
dl 0
loc 72
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A generateXml() 0 7 2
A rejectNonVisitableUrls() 0 20 2
A __construct() 0 6 1
A prepareOnlineUrls() 0 6 1
A generate() 0 7 1
A crawlableUrlGenerator() 0 4 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Thinktomorrow\Chief\System\Sitemap;
5
6
use GuzzleHttp\Pool;
7
use GuzzleHttp\Client;
8
use Spatie\Sitemap\Sitemap;
9
use GuzzleHttp\Psr7\Request;
10
use GuzzleHttp\Psr7\Response;
11
use Illuminate\Support\Collection;
12
use Thinktomorrow\Chief\Urls\UrlRecord;
13
use GuzzleHttp\Exception\RequestException;
14
use Thinktomorrow\Chief\Urls\ProvidesUrl\ProvidesUrl;
15
16
class SitemapXml
17
{
18
    /** @var Sitemap */
19
    private $sitemap;
20
21
    /** @var Client */
22
    private $httpClient;
23
24
    /** @var Collection */
25
    private $urls;
26
27
    public function __construct(Sitemap $sitemap, Client $httpClient)
28
    {
29
        $this->sitemap = $sitemap;
30
        $this->httpClient = $httpClient;
31
32
        $this->urls = collect();
0 ignored issues
show
Documentation Bug introduced by
It seems like collect() of type Tightenco\Collect\Support\Collection is incompatible with the declared type Illuminate\Support\Collection of property $urls.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
33
    }
34
35
    public function generate(string $locale): string
36
    {
37
        $this->prepareOnlineUrls($locale);
38
39
        $this->rejectNonVisitableUrls($locale);
0 ignored issues
show
Unused Code introduced by
The call to Thinktomorrow\Chief\Syst...ejectNonVisitableUrls() has too many arguments starting with $locale. ( Ignorable by Annotation )

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

39
        $this->/** @scrutinizer ignore-call */ 
40
               rejectNonVisitableUrls($locale);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
40
41
        return $this->generateXml();
42
    }
43
44
    private function generateXml(): string
45
    {
46
        foreach($this->urls as $url) {
47
            $this->sitemap->add($url);
48
        }
49
50
        return $this->sitemap->render();
51
    }
52
53
    private function prepareOnlineUrls(string $locale): void
54
    {
55
        $models = UrlRecord::allOnlineModels($locale);
56
57
        $this->urls = $models->map(function(ProvidesUrl $model) use($locale){
58
            return $model->url($locale);
59
        });
60
    }
61
62
    private function rejectNonVisitableUrls()
63
    {
64
        $pool = new Pool($this->httpClient, $this->crawlableUrlGenerator(), [
65
            'concurrency' => 5,
66
            'fulfilled' => function (Response $response, $index) {
67
                if($response->getStatusCode() !== \Symfony\Component\HttpFoundation\Response::HTTP_OK){
68
                    unset($this->urls[$index]);
69
                }
70
            },
71
            'rejected' => function (RequestException $reason, $index) {
72
            trap($reason);
73
                unset($this->urls[$index]);
74
            },
75
        ]);
76
77
        // Initiate the transfers and create a promise
78
        $promise = $pool->promise();
79
80
        // Force the pool of requests to complete.
81
        $promise->wait();
82
    }
83
84
    private function crawlableUrlGenerator(): \Generator
85
    {
86
        foreach($this->urls as $index => $url){
87
            yield $index => new Request('GET', $url);
88
        }
89
    }
90
}
91