Completed
Push — master ( 0ba7a7...b86115 )
by Freek
01:17
created

MixedContentExtractor::extract()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
cc 2
eloc 15
nc 1
nop 2
1
<?php
2
3
namespace Spatie\MixedContentScanner;
4
5
use Spatie\Crawler\Url;
6
use Illuminate\Support\Collection;
7
use Symfony\Component\DomCrawler\Link;
8
use Symfony\Component\DomCrawler\Crawler as DomCrawler;
9
10
class MixedContentExtractor
11
{
12
    public static function extract(string $html, string $currentUri): array
13
    {
14
        return static::getSearchNodes()
15
            ->mapSpread(function ($tagName, $attribute) use ($html, $currentUri) {
16
                return (new DomCrawler($html, $currentUri))
17
                    ->filterXPath("//{$tagName}[@{$attribute}]")
18
                    ->reduce(function (DomCrawler $node) {
19
                        return ! self::isShortLink($node);
20
                    })
21
                    ->each(function (DomCrawler $node) use ($tagName, $attribute) {
22
                        $url = Url::create($node->attr($attribute));
23
24
                        return $url->scheme === 'http' ? [$tagName, $url] : null;
25
                    });
26
            })
27
            ->flatten(1)
28
            ->filter()
29
            ->mapSpread(function ($tagName, $mixedContentUrl) use ($currentUri) {
30
                return new MixedContent($tagName, $mixedContentUrl, Url::create($currentUri));
31
            })
32
            ->toArray();
33
    }
34
35
    protected static function getSearchNodes(): Collection
36
    {
37
        return collect([
38
            ['audio', 'src'],
39
            ['embed', 'src'],
40
            ['form', 'action'],
41
            ['link', 'href'],
42
            ['iframe', 'src'],
43
            ['img', 'src'],
44
            ['img', 'srcset'],
45
            ['object', 'data'],
46
            ['param', 'value'],
47
            ['script', 'src'],
48
            ['source', 'src'],
49
            ['source', 'srcset'],
50
            ['video', 'src'],
51
        ]);
52
    }
53
54
    protected static function isShortLink(DomCrawler $node)
55
    {
56
        $relAttribute = $node->getNode(0)->attributes->getNamedItem('rel');
57
58
        if (is_null($relAttribute)) {
59
            return false;
60
        }
61
62
        return strtolower($relAttribute->nodeValue) === 'shortlink';
63
    }
64
}
65