Completed
Push — master ( 8f1125...aa557b )
by Tom
02:47
created

CssToXpath::parseAttr()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 15
rs 9.2
cc 4
eloc 11
nc 4
nop 1
1
<?php
2
/* @description     Transformation Style Sheets - Revolutionising PHP templating    *
3
 * @author          Tom Butler [email protected]                                             *
4
 * @copyright       2015 Tom Butler <[email protected]> | https://r.je/                      *
5
 * @license         http://www.opensource.org/licenses/bsd-license.php  BSD License *
6
 * @version         1.0                                                             */
7
namespace Transphporm;
8
class CssToXpath {
9
	private $specialChars = [' ', '.', '>', '~', '#', ':', '[', ']'];
10
	private $translators = [];
11
	private $css;
12
	private $depth;
13
	private $valueParser;
14
15
	public function __construct($css, ValueParser $valueParser, $prefix = '') {
16
		$this->css = str_replace([' >', '> '],['>', '>'], trim($css));
17
		$this->valueParser = $valueParser;
18
		$this->translators = [
19
			' ' => function($string) use ($prefix) { return '//' . $prefix . $string;	},
20
			'' => function($string) use ($prefix) { return '/' . $prefix . $string;	},
21
			'>' => function($string) use ($prefix) { return '/' . $prefix  . $string; },
22
			'#' => function($string) { return '[@id=\'' . $string . '\']'; },
23
			'.' => function($string) { return '[contains(concat(\' \', normalize-space(@class), \' \'), \' ' . $string . ' \')]'; }, 
24
			'[' => function($string) { return '[@' . $this->parseAttr($string) . ']';	},
25
			']' => function() {	return ''; }
26
		];
27
	}
28
29
	private function createSelector() {
30
		$selector = new \stdclass;
31
		$selector->type = '';
32
		$selector->string = '';
33
		return $selector;
34
	}
35
36
	private function parseAttr($attr) {
37
		$comparators = ['!=', '='];
38
		foreach ($comparators as $comparator) {
39
			if (strpos($attr, $comparator) !== false) {
40
				$parts = explode($comparator, $attr);
41
				$parts = array_map(function($val) {
42
					return implode($this->valueParser->parse($val));
43
				}, $parts);
44
				if (isset($parts[1])) $parts[1] = '"' . $parts[1] . '"';
45
				return implode($comparator, $parts);
46
			}
47
		}
48
49
		return $attr;
50
	}
51
52
	//split the css into indivudal functions
53
	private function split($css) {
54
		$selectors = [];
55
		$selector = $this->createSelector();
56
		$selectors[] = $selector;
57
58
		for ($i = 0; $i < strlen($css); $i++) {
59
			if (in_array($css[$i], $this->specialChars)) {
60
				$selector = $this->createSelector();
61
				$selector->type = $css[$i];
62
				$selectors[] = $selector;
63
			}
64
			else $selector->string .= $css[$i];			
65
		}
66
		return $selectors;
67
	}
68
69
	public function getXpath() {
70
		$css = explode(':', $this->css)[0];
71
		$selectors = $this->split($css);
72
		$this->depth = count($selectors);
73
		$xpath = '/';
74
		foreach ($selectors as $selector) {
75
			if (isset($this->translators[$selector->type])) $xpath .= $this->translators[$selector->type]($selector->string);
76
		}
77
78
		$xpath = str_replace('/[', '/*[', $xpath);
79
80
		return $xpath;
81
	}
82
83
	public function getDepth() {
84
		return $this->depth;
85
	}
86
	
87
	public function getPseudo() {
88
		$parts = explode(':', $this->css);
89
		array_shift($parts);
90
		return $parts;
91
	}
92
}