1 | <?php |
||
9 | class PseudoMatcher { |
||
10 | private $pseudo; |
||
11 | private $dataFunction; |
||
12 | |||
13 | public function __construct($pseudo, DataFunction $dataFunction) { |
||
17 | |||
18 | public function matches($element) { |
||
19 | $matches = true; |
||
20 | $functions = ['attribute', 'nth', 'not']; |
||
21 | |||
22 | foreach ($this->pseudo as $pseudo) { |
||
23 | foreach ($functions as $func) { |
||
24 | $matches = $matches && $this->$func($pseudo, $element); |
||
25 | } |
||
26 | } |
||
27 | return $matches; |
||
28 | } |
||
29 | |||
30 | private function betweenBrackets($string, $openChr, $closingChr, $start = 0) { |
||
31 | $open = strpos($string, $openChr, $start); |
||
32 | $close = strpos($string, $closingChr, $open); |
||
33 | |||
34 | $cPos = $open+1; |
||
35 | while (($cPos = strpos($string, $openChr, $cPos+1)) !== false && $cPos < $close) $close = strpos($string, $closingChr, $close+1); |
||
36 | |||
37 | return substr($string, $open+1, $close-$open-1); |
||
38 | } |
||
39 | |||
40 | private function attribute($pseudo, $element) { |
||
41 | $pos = strpos($pseudo, '['); |
||
42 | if ($pos === false) return true; |
||
43 | |||
44 | $name = substr($pseudo, 0, $pos); |
||
45 | if (!is_callable([$this->dataFunction, $name])) return true; |
||
46 | |||
47 | $criteria = $this->betweenBrackets($pseudo, '[', ']'); |
||
48 | |||
49 | if (strpos($pseudo, '=') === false) { |
||
50 | $lookupValue = $this->dataFunction->$name([$criteria], $element); |
||
51 | return $lookupValue !== null; |
||
52 | } |
||
53 | list ($field, $value) = explode('=', $criteria); |
||
54 | |||
55 | $operator = $this->getOperator($field); |
||
56 | $lookupValue = $this->dataFunction->$name([trim($field, $operator)], $element); |
||
57 | |||
58 | return $this->processOperator($operator, $lookupValue, $this->parseValue(trim($value, '"'))); |
||
59 | } |
||
60 | |||
61 | //Currently only not is supported, but this is separated out to support others in future |
||
62 | private function processOperator($operator, $lookupValue, $value) { |
||
66 | |||
67 | private function parseValue($value) { |
||
72 | |||
73 | private function getOperator($field) { |
||
79 | |||
80 | private function nth($pseudo, $element) { |
||
91 | |||
92 | private function not($pseudo, $element) { |
||
93 | if (strpos($pseudo, 'not') === 0) { |
||
94 | $valueParser = new \Transphporm\Parser\Value($this->dataFunction); |
||
109 | |||
110 | public function attr() { |
||
120 | |||
121 | public function header($element) { |
||
128 | |||
129 | private function odd($num) { |
||
132 | |||
133 | private function even($num) { |
||
136 | |||
137 | private function getBetween($string, $start, $end) { |
||
143 | |||
144 | public function getPseudo() { |
||
147 | } |