Completed
Branch XPathConvertorRefactor (0e46c7)
by Josh
09:34
created

MultiByteStringManipulation::convertSubstring()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4222
c 0
b 0
f 0
cc 5
nc 4
nop 3
1
<?php
2
3
/**
4
* @package   s9e\TextFormatter
5
* @copyright Copyright (c) 2010-2018 The s9e Authors
6
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
7
*/
8
namespace s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors;
9
10
class MultiByteStringManipulation extends AbstractConvertor
11
{
12
	/**
13
	* {@inheritdoc}
14
	*/
15
	public function getRegexpGroups()
16
	{
17
		return [
18
			'Substring' => 'String'
19
		];
20
	}
21
22
	/**
23
	* {@inheritdoc}
24
	*/
25
	public function getRegexps()
26
	{
27
		return [
28
			'Substring' => 'substring \\( ((?&String)) , ((?&Attribute)|(?&Math)|(?&Number)) (?:, ((?&Attribute)|(?&Math)|(?&Number)))? \\)'
29
		];
30
	}
31
32
	/**
33
	* Convert a substring() function call
34
	*
35
	* @param  string $exprString
36
	* @param  string $exprPos
37
	* @param  string $exprLen
38
	* @return string
39
	*/
40
	public function convertSubstring($exprString, $exprPos, $exprLen = null)
41
	{
42
		// Try to fix negative lengths when possible
43
		if (is_numeric($exprPos) && is_numeric($exprLen) && $exprPos < 1)
44
		{
45
			$exprLen += $exprPos - 1;
46
		}
47
48
		$args   = [];
49
		$args[] = $this->convert($exprString);
50
		$args[] = $this->convertPos($exprPos);
51
		$args[] = (isset($exprLen)) ? $this->convertLen($exprLen) : 'null';
52
		$args[] = "'utf-8'";
53
54
		return 'mb_substr(' . implode(',', $args) . ')';
55
	}
56
57
	/**
58
	* Convert the length expression of a substring() call
59
	*
60
	* @param  string $expr
61
	* @return string
62
	*/
63
	protected function convertLen($expr)
64
	{
65
		// NOTE: negative values for the second argument do not produce the same result as
66
		//       specified in XPath if the argument is not a literal number
67
		if (is_numeric($expr))
68
		{
69
			return (string) max(0, $expr);
70
		}
71
72
		return 'max(0,' . $this->convert($expr) . ')';
73
	}
74
75
	/**
76
	* Convert the position expression of a substring() call
77
	*
78
	* @param  string $expr
79
	* @return string
80
	*/
81
	protected function convertPos($expr)
82
	{
83
		if (is_numeric($expr))
84
		{
85
			return (string) max(0, $expr - 1);
86
		}
87
88
		return 'max(0,' . $this->convert($expr) . '-1)';
89
	}
90
}