Completed
Push — master ( dbcf6b...d53ab6 )
by Peter
44:13 queued 37:37
created

NodeMapper::extractHtml()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace TreeHouse\IoBundle\Scrape\Modifier\Item\Mapper;
4
5
use Symfony\Component\DomCrawler\Crawler;
6
use Symfony\Component\HttpFoundation\ParameterBag;
7
use TreeHouse\Feeder\Modifier\Item\Mapper\MapperInterface;
8
9
class NodeMapper implements MapperInterface, CrawlerAwareInterface
10
{
11
    /**
12
     * @var Crawler
13
     */
14
    protected $crawler;
15
16
    /**
17
     * @var array
18
     */
19
    protected $mapping = [];
20
21
    /**
22
     * @var string[]
23
     */
24
    protected $filters = [];
25
26
    /**
27
     * @var callable[]
28
     */
29
    protected $extractors = [];
30
31
    /**
32
     * @param array $mapping
33
     */
34 24
    public function __construct(array $mapping)
35
    {
36 24
        foreach ($mapping as $name => $selector) {
37 14
            if (is_string($selector)) {
38 8
                $extractor = [$this, 'extractHtml'];
39 10
            } elseif (is_array($selector) && sizeof($selector) === 2) {
40 8
                list($selector, $extractor) = $selector;
41
            } else {
42 2
                throw new \InvalidArgumentException('A mapping value must be either a string or array<string, callable>');
43
            }
44
45 12
            $this->addMapping($name, $selector, $extractor);
46
        }
47 20
    }
48
49
    /**
50
     * @return array
51
     */
52 6
    public function getMapping()
53
    {
54 6
        return $this->mapping;
55
    }
56
57
    /**
58
     * @param string          $name
59
     * @param string          $selector
60
     * @param string|callable $extractor
61
     */
62 20
    public function addMapping($name, $selector, $extractor = 'extractHtml')
63
    {
64 20
        if (is_string($extractor) && method_exists($this, $extractor)) {
65 8
            $extractor = [$this, $extractor];
66
        }
67
68 20
        if (!is_callable($extractor)) {
69 4
            throw new \InvalidArgumentException(
70 4
                sprintf('The extractor of a mapping must be a callable, but got %s', json_encode($extractor))
71
            );
72
        }
73
74 16
        $this->mapping[$name] = $selector;
75 16
        $this->extractors[$name] = $extractor;
76 16
        $this->filters[$name] = 'filter';
77
78 16
        if (preg_match('~^//~', $selector) || strpos($selector, 'descendant-or-self::') === 0) {
79
            $this->filters[$name] = 'filterXpath';
80
        }
81 16
    }
82
83
    /**
84
     * @inheritdoc
85
     */
86 4
    public function setCrawler(Crawler $crawler)
87
    {
88 4
        $this->crawler = $crawler;
89 4
    }
90
91
    /**
92
     * @param ParameterBag $item
93
     *
94
     * @throws \LogicException
95
     *
96
     * @return ParameterBag
97
     */
98 6
    public function map(ParameterBag $item)
99
    {
100 6
        if (null === $this->crawler) {
101 2
            throw new \LogicException('setCrawler() should be called before map()');
102
        }
103
104 4
        foreach ($this->mapping as $name => $selector) {
105 4
            $filter = $this->filters[$name];
106 4
            $extractor = $this->extractors[$name];
107
108
            /** @var Crawler $node */
109 4
            $node = $this->crawler->$filter($selector);
110
111 4
            if ($node->count() === 0) {
112
                $value = null;
113
            } else {
114 4
                $value = call_user_func($extractor, $name, $node);
115
            }
116
117 4
            $item->set($name, $value);
118
        }
119
120 4
        return $item;
121
    }
122
123
    /**
124
     * @param string  $field
125
     * @param Crawler $node
126
     *
127
     * @return string
128
     */
129 2
    protected function extractHtml($field, Crawler $node)
130
    {
131 2
        return $node->html();
132
    }
133
134
    /**
135
     * @param string  $field
136
     * @param Crawler $node
137
     *
138
     * @return string
139
     */
140 2
    protected function extractText($field, Crawler $node)
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
141
    {
142 2
        return $node->text();
143
    }
144
}
145