1<?php 2 3/** 4* @package s9e\TextFormatter 5* @copyright Copyright (c) 2010-2021 The s9e authors 6* @license http://www.opensource.org/licenses/mit-license.php The MIT License 7*/ 8namespace s9e\TextFormatter\Configurator\RendererGenerators\PHP\XPathConvertor\Convertors; 9 10class SingleByteStringFunctions extends AbstractConvertor 11{ 12 /** 13 * {@inheritdoc} 14 */ 15 public function getMatchers(): array 16 { 17 return [ 18 'Boolean:BooleanFunction:Contains' => 'contains \\( ((?&String)) , ((?&String)) \\)', 19 'Boolean:BooleanFunction:EndsWith' => 'ends-with \\( ((?&String)) , ((?&String)) \\)', 20 'Boolean:BooleanFunction:NotContains' => 'not \\( contains \\( ((?&String)) , ((?&String)) \\) \\)', 21 'Boolean:BooleanFunction:NotEndsWith' => 'not \\( ends-with \\( ((?&String)) , ((?&String)) \\) \\)', 22 'Boolean:BooleanFunction:NotStartsWith' => 'not \\( starts-with \\( ((?&String)) , ((?&String)) \\) \\)', 23 'Boolean:BooleanFunction:StartsWith' => 'starts-with \\( ((?&String)) , ((?&String)) \\)', 24 'Number:StringLength' => 'string-length \\( ((?&String))? \\)' 25 ]; 26 } 27 28 /** 29 * Convert a call to contains() 30 * 31 * @param string $haystack Expression for the haystack part of the call 32 * @param string $needle Expression for the needle part of the call 33 * @return string 34 */ 35 public function parseContains($haystack, $needle) 36 { 37 return $this->generateContains($haystack, $needle, true); 38 } 39 40 /** 41 * Convert a call to ends-with() 42 * 43 * @param string $string Expression for the string part of the call 44 * @param string $substring Expression for the substring part of the call 45 * @return string 46 */ 47 public function parseEndsWith($string, $substring) 48 { 49 return $this->generateEndsWith($string, $substring, true); 50 } 51 52 /** 53 * Convert a call to not(contains()) 54 * 55 * @param string $haystack Expression for the haystack part of the call 56 * @param string $needle Expression for the needle part of the call 57 * @return string 58 */ 59 public function parseNotContains($haystack, $needle) 60 { 61 return $this->generateContains($haystack, $needle, false); 62 } 63 64 /** 65 * Convert a call to not(ends-with()) 66 * 67 * @param string $string Expression for the string part of the call 68 * @param string $substring Expression for the substring part of the call 69 * @return string 70 */ 71 public function parseNotEndsWith($string, $substring) 72 { 73 return $this->generateEndsWith($string, $substring, false); 74 } 75 76 /** 77 * Convert a call to not(starts-with()) 78 * 79 * @param string $string Expression for the string part of the call 80 * @param string $substring Expression for the substring part of the call 81 * @return string 82 */ 83 public function parseNotStartsWith($string, $substring) 84 { 85 return $this->generateStartsWith($string, $substring, false); 86 } 87 88 /** 89 * Convert a call to starts-with() 90 * 91 * @param string $string Expression for the string part of the call 92 * @param string $substring Expression for the substring part of the call 93 * @return string 94 */ 95 public function parseStartsWith($string, $substring) 96 { 97 return $this->generateStartsWith($string, $substring, true); 98 } 99 100 /** 101 * Convert a call to string-length() 102 * 103 * @param string $expr 104 * @return string 105 */ 106 public function parseStringLength($expr = '.') 107 { 108 return "preg_match_all('(.)su'," . $this->recurse($expr) . ')'; 109 } 110 111 /** 112 * Generate the code for a call to contains() 113 * 114 * @param string $haystack Expression for the haystack part of the call 115 * @param string $needle Expression for the needle part of the call 116 * @param bool $bool Return value for a positive match 117 * @return string 118 */ 119 protected function generateContains($haystack, $needle, $bool) 120 { 121 $operator = ($bool) ? '!==' : '==='; 122 123 return '(strpos(' . $this->recurse($haystack) . ',' . $this->recurse($needle) . ')' . $operator . 'false)'; 124 } 125 126 /** 127 * Generate the code for a call to ends-with() 128 * 129 * @param string $string Expression for the string part of the call 130 * @param string $substring Expression for the substring part of the call 131 * @param bool $bool Return value for a positive match 132 * @return string 133 */ 134 protected function generateEndsWith($string, $substring, $bool) 135 { 136 return (preg_match('(^(?:\'[^\']+\'|"[^"]+")$)D', $substring)) 137 ? $this->generateEndsWithLiteral($string, $substring, $bool) 138 : $this->generateEndsWithExpression($string, $substring, $bool); 139 } 140 141 /** 142 * Generate the code for a call to ends-with() where the second argument is a literal string 143 * 144 * @param string $string Expression for the string part of the call 145 * @param string $substring Expression for a literal substring 146 * @param bool $bool Return value for a positive match 147 * @return string 148 */ 149 protected function generateEndsWithLiteral($string, $substring, $bool) 150 { 151 $operator = ($bool) ? '===' : '!=='; 152 153 return '(substr(' . $this->recurse($string) . ',-' . (strlen($substring) - 2) . ')' . $operator . $this->recurse($substring) . ')'; 154 } 155 156 /** 157 * Generate the code for a call to ends-with() 158 * 159 * @param string $string Expression for the string part of the call 160 * @param string $substring Expression for the substring part of the call 161 * @param bool $bool Return value for a positive match 162 * @return string 163 */ 164 protected function generateEndsWithExpression($string, $substring, $bool) 165 { 166 $operator = ($bool) ? '' : '!'; 167 168 return $operator . "preg_match('('.preg_quote(" . $this->recurse($substring) . ").'$)D'," . $this->recurse($string) . ')'; 169 } 170 171 /** 172 * Generate the code for a call to starts-with() 173 * 174 * @param string $string Expression for the string part of the call 175 * @param string $substring Expression for the substring part of the call 176 * @param bool $bool Return value for a positive match 177 * @return string 178 */ 179 protected function generateStartsWith($string, $substring, $bool) 180 { 181 $operator = ($bool) ? '===' : '!=='; 182 183 return '(strpos(' . $this->recurse($string) . ',' . $this->recurse($substring) . ')' . $operator . '0)'; 184 } 185}