Completed
Pull Request — master (#27)
by
unknown
06:13
created

MixedContentExtractor::hrefIsCss()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Spatie\MixedContentScanner;
4
5
use Exception;
6
use GuzzleHttp\Psr7\Uri;
7
use Illuminate\Support\Collection;
8
use Psr\Http\Message\UriInterface;
9
use Symfony\Component\DomCrawler\Crawler as DomCrawler;
10
11
class MixedContentExtractor
12
{
13
    public static function extract(string $html, UriInterface $currentUri): array
14
    {
15
        $linkedCss = [];
16
        $mixed = static::getSearchNodes()
17
            ->mapSpread(function ($tagName, $attribute) use ($html, $currentUri, &$linkedCss) {
18
                return (new DomCrawler($html, (string) $currentUri))
19
                    ->filterXPath("//{$tagName}[@{$attribute}]")
20
                    ->reduce(function (DomCrawler $node) {
21
                        return !self::isShortLink($node);
22
                    })
23
                    ->each(function (DomCrawler $node) use ($tagName, $attribute, &$linkedCss) {
24
                        try {
25
                            $url = new Uri($node->attr($attribute));
26
27
                            if ($tagName === 'link' && $attribute === 'href') {
28
                                if ($node->attr('rel') !== 'stylesheet') {
29
                                    return;
30
                                }
31
32
                                if (self::hrefIsCss($url)) {
33
                                    $linkedCss[] = $url;
34
                                }
35
                            }
36
37
                            return $url->getScheme() === 'http' ? [$tagName, $url] : null;
38
                        } catch (Exception $e) {
39
                            // ignore invalid links
40
                        }
41
                    });
42
            })
43
            ->flatten(1)
44
            ->filter()
45
            ->mapSpread(function ($tagName, $mixedContentUrl) use ($currentUri) {
46
                return new MixedContent($tagName, $mixedContentUrl, $currentUri);
47
            })
48
            ->toArray();
49
50
        return [$mixed, $linkedCss];
51
    }
52
53
    protected static function getSearchNodes(): Collection
54
    {
55
        return collect([
56
            ['audio', 'src'],
57
            ['embed', 'src'],
58
            ['form', 'action'],
59
            ['link', 'href'],
60
            ['iframe', 'src'],
61
            ['img', 'src'],
62
            ['img', 'srcset'],
63
            ['object', 'data'],
64
            ['param', 'value'],
65
            ['script', 'src'],
66
            ['source', 'src'],
67
            ['source', 'srcset'],
68
            ['video', 'src'],
69
        ]);
70
    }
71
72
    protected static function isShortLink(DomCrawler $node): bool
73
    {
74
        $relAttribute = $node->getNode(0)->attributes->getNamedItem('rel');
75
76
        if (is_null($relAttribute)) {
77
            return false;
78
        }
79
80
        return strtolower($relAttribute->nodeValue) === 'shortlink';
81
    }
82
83
    protected static function hrefIsCss(UriInterface $uri): bool
84
    {
85
        return ((strpos((string) $uri, '.css') !== false));
86
    }
87
}
88