Passed
Push — master ( e94418...dc9630 )
by Jeroen
01:30
created

Diglett::getText()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 18
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace Jerodev\Diglett;
4
5
use Symfony\Component\DomCrawler\Crawler;
6
7
class Diglett
8
{
9
    /**
10
     *  The Symfony DomCrawler to work with.
11
     *
12
     *  @var Crawler
13
     */
14
    private $crawler;
15
16
    /**
17
     *  The css selector parser
18
     * 
19
     *  @var CssFilterParser
20
     */
21
    private $cssFilterParser;
22
23
    /**
24
     *  Create a diglett instance from a Symfony Crawler.
25
     *
26
     *  @param Crawler
27
     *  @param array $cssFilter An array of extra ICssFilterl classes to filter on
28
     */
29
    public function __construct(Crawler $crawler, array $cssFilters = [])
30
    {
31
        $this->crawler = $crawler;
32
        $this->cssFilterParser = new CssFilterParser($cssFilters);
33
    }
34
35
    /**
36
     *  Get the underlying crawler object
37
     *
38
     *  @return Crawler
39
     */
40
    public function getCrawler(): Crawler
41
    {
42
        return $this->crawler;
43
    }
44
45
    /**
46
     *  Use special css selectors to filter on the current node collection
47
     * 
48
     *  @param string $selector
49
     *  @return Crawler|null
50
     */
51
    public function filter(string $selector): ?Crawler 
52
    {
53
        $parsedSelector = $this->cssFilterParser->parse($selector);
54
55
        $crawler = $this->getCrawler();
56
        foreach ($parsedSelector as $part)
57
        {
58
            $crawler = $crawler->filter($part['selector']);
59
60
            foreach ($part['functions'] as $function)
61
            {
62
                $crawler = $function->filterNodes($crawler);
63
            }
64
65
            if (empty($crawler) || $crawler->count() === 0)
66
            {
67
                break;
68
            }
69
        }
70
71
        return $crawler;
72
    }
73
74
75
    /**
76
     *  Use special css selectors to fetch several values
77
     *
78
     *  @param array $selectors
79
     *  @return array
80
     */
81
    public function getTexts(array $selectors): array
82
    {
83
        $results = [];
84
        foreach ($selectors as $key => $value)
85
        {
86
            $results[$key] = $this->getText($value);
87
        }
88
89
        return $results;
90
    }
91
92
    /**
93
     *  Get the value for a single special css selector
94
     *
95
     *  @param string $selector
96
     *  @return string|null
97
     */
98
    public function getText(string $selector): ?string
99
    {
100
        $attribute = null;
101
        $selector = preg_replace_callback(
102
            '/\{(.*?)\}$/',
103
            function ($matches) use (&$attribute) {
104
                $attribute = $matches[1] ?? null;
105
            },
106
            $selector
107
        );
108
109
        $crawler = $this->filter($selector);
110
        if ($crawler === null)
111
        {
112
            return null;
113
        }
114
115
        return $attribute === null ? $crawler->text() : $crawler->attr($attribute);
116
    }
117
}
118