Passed
Push — master ( 99b7f0...3ffff4 )
by Josh
03:49
created

XPath::exportString()   A

Complexity

Conditions 6
Paths 7

Size

Total Lines 32
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 32
ccs 15
cts 15
cp 1
rs 9.2222
cc 6
nc 7
nop 1
crap 6
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2019 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Utils;
9
10
use InvalidArgumentException;
11
12
abstract class XPath
13
{
14
	/**
15
	* Export a literal as an XPath expression
16
	*
17
	* @param  mixed  $value Literal, e.g. "foo"
18
	* @return string        XPath expression, e.g. "'foo'"
19
	*/
20 10
	public static function export($value)
21
	{
22 10
		$callback = get_called_class() . '::export' . ucfirst(gettype($value));
23 10
		if (!is_callable($callback))
24
		{
25 1
			throw new InvalidArgumentException(__METHOD__ . '() cannot export non-scalar values');
26
		}
27
28 9
		return $callback($value);
29
	}
30
31
	/**
32
	* Export given boolean value
33
	*
34
	* @param  bool   $value
35
	* @return string
36
	*/
37 2
	protected static function exportBoolean(bool $value): string
38
	{
39 2
		return ($value) ? 'true()' : 'false()';
40
	}
41
42
	/**
43
	* Export given float value
44
	*
45
	* @param  float  $value
46
	* @return string
47
	*/
48 2
	protected static function exportDouble(float $value): string
49
	{
50 2
		if (!is_finite($value))
51
		{
52
			throw new InvalidArgumentException(__METHOD__ . '() cannot export irrational numbers');
53
		}
54
55
		// Avoid locale issues by using sprintf()
56 2
		return preg_replace('(\\.?0+$)', '', sprintf('%F', $value));
57
	}
58
59
	/**
60
	* Export given integer value
61
	*
62
	* @param  integer $value
63
	* @return string
64
	*/
65 1
	protected static function exportInteger(int $value): string
66
	{
67 1
		return (string) $value;
68
	}
69
70
	/**
71
	* Export a string as an XPath expression
72
	*
73
	* @param  string $str Literal, e.g. "foo"
74
	* @return string      XPath expression, e.g. "'foo'"
75
	*/
76 4
	protected static function exportString(string $str): string
77
	{
78
		// foo becomes 'foo'
79 4
		if (strpos($str, "'") === false)
80
		{
81 1
			return "'" . $str . "'";
82
		}
83
84
		// d'oh becomes "d'oh"
85 3
		if (strpos($str, '"') === false)
86
		{
87 1
			return '"' . $str . '"';
88
		}
89
90
		// This string contains both ' and ". XPath 1.0 doesn't have a mechanism to escape quotes,
91
		// so we have to get creative and use concat() to join chunks in single quotes and chunks
92
		// in double quotes
93 2
		$toks = [];
94 2
		$c    = '"';
95 2
		$pos  = 0;
96 2
		while ($pos < strlen($str))
97
		{
98 2
			$spn = strcspn($str, $c, $pos);
99 2
			if ($spn)
100
			{
101 2
				$toks[] = $c . substr($str, $pos, $spn) . $c;
102 2
				$pos   += $spn;
103
			}
104 2
			$c = ($c === '"') ? "'" : '"';
105
		}
106
107 2
		return 'concat(' . implode(',', $toks) . ')';
108
	}
109
}