1<?php 2namespace TYPO3\CMS\Core\Utility; 3 4/* 5 * This file is part of the TYPO3 CMS project. 6 * 7 * It is free software; you can redistribute it and/or modify it under 8 * the terms of the GNU General Public License, either version 2 9 * of the License, or any later version. 10 * 11 * For the full copyright and license information, please read the 12 * LICENSE.txt file that was distributed with this source code. 13 * 14 * The TYPO3 project - inspiring people to share! 15 */ 16 17/** 18 * Class with helper functions for string handling 19 */ 20class StringUtility 21{ 22 /** 23 * Returns TRUE if $haystack begins with $needle. 24 * The input string is not trimmed before and search is done case sensitive. 25 * 26 * @param string $haystack Full string to check 27 * @param string $needle Reference string which must be found as the "first part" of the full string 28 * @throws \InvalidArgumentException 29 * @return bool TRUE if $needle was found to be equal to the first part of $haystack 30 */ 31 public static function beginsWith($haystack, $needle) 32 { 33 // Sanitize $haystack and $needle 34 if (is_array($haystack) || is_object($haystack) || $haystack === null || (string)$haystack != $haystack) { 35 throw new \InvalidArgumentException( 36 '$haystack can not be interpreted as string', 37 1347135546 38 ); 39 } 40 if (is_array($needle) || is_object($needle) || (string)$needle != $needle || strlen($needle) < 1) { 41 throw new \InvalidArgumentException( 42 '$needle can not be interpreted as string or has zero length', 43 1347135547 44 ); 45 } 46 $haystack = (string)$haystack; 47 $needle = (string)$needle; 48 return $needle !== '' && strpos($haystack, $needle) === 0; 49 } 50 51 /** 52 * Returns TRUE if $haystack ends with $needle. 53 * The input string is not trimmed before and search is done case sensitive. 54 * 55 * @param string $haystack Full string to check 56 * @param string $needle Reference string which must be found as the "last part" of the full string 57 * @throws \InvalidArgumentException 58 * @return bool TRUE if $needle was found to be equal to the last part of $haystack 59 */ 60 public static function endsWith($haystack, $needle) 61 { 62 // Sanitize $haystack and $needle 63 if (is_array($haystack) || is_object($haystack) || $haystack === null || (string)$haystack != $haystack) { 64 throw new \InvalidArgumentException( 65 '$haystack can not be interpreted as string', 66 1347135544 67 ); 68 } 69 if (is_array($needle) || is_object($needle) || (string)$needle != $needle || strlen($needle) < 1) { 70 throw new \InvalidArgumentException( 71 '$needle can not be interpreted as string or has no length', 72 1347135545 73 ); 74 } 75 $haystackLength = strlen($haystack); 76 $needleLength = strlen($needle); 77 if (!$haystackLength || $needleLength > $haystackLength) { 78 return false; 79 } 80 $position = strrpos((string)$haystack, (string)$needle); 81 return $position !== false && $position === $haystackLength - $needleLength; 82 } 83 84 /** 85 * This function generates a unique id by using the more entropy parameter. 86 * Furthermore the dots are removed so the id can be used inside HTML attributes e.g. id. 87 * 88 * @param string $prefix 89 * @return string 90 */ 91 public static function getUniqueId($prefix = '') 92 { 93 $uniqueId = uniqid($prefix, true); 94 return str_replace('.', '', $uniqueId); 95 } 96 97 /** 98 * Escape a CSS selector to be used for DOM queries 99 * 100 * This method takes care to escape any CSS selector meta character. 101 * The result may be used to query the DOM like $('#' + escapedSelector) 102 * 103 * @param string $selector 104 * @return string 105 */ 106 public static function escapeCssSelector(string $selector): string 107 { 108 return preg_replace('/([#:.\\[\\],=@])/', '\\\\$1', $selector); 109 } 110 111 /** 112 * Removes the Byte Order Mark (BOM) from the input string. This method supports UTF-8 encoded strings only! 113 * 114 * @param string $input 115 * @return string 116 */ 117 public static function removeByteOrderMark(string $input): string 118 { 119 if (strpos($input, "\xef\xbb\xbf") === 0) { 120 $input = substr($input, 3); 121 } 122 123 return $input; 124 } 125 126 /** 127 * Matching two strings against each other, supporting a "*" wildcard (match many) or a "?" wildcard (match one= or (if wrapped in "/") PCRE regular expressions 128 * 129 * @param string $haystack The string in which to find $needle. 130 * @param string $needle The string to find in $haystack 131 * @return bool Returns TRUE if $needle matches or is found in (according to wildcards) $haystack. E.g. if $haystack is "Netscape 6.5" and $needle is "Net*" or "Net*ape" then it returns TRUE. 132 */ 133 public static function searchStringWildcard($haystack, $needle): bool 134 { 135 $result = false; 136 if ($haystack === $needle) { 137 $result = true; 138 } elseif ($needle) { 139 if (preg_match('/^\\/.+\\/$/', $needle)) { 140 // Regular expression, only "//" is allowed as delimiter 141 $regex = $needle; 142 } else { 143 $needle = str_replace(['*', '?'], ['%%%MANY%%%', '%%%ONE%%%'], $needle); 144 $regex = '/^' . preg_quote($needle, '/') . '$/'; 145 // Replace the marker with .* to match anything (wildcard) 146 $regex = str_replace(['%%%MANY%%%', '%%%ONE%%%'], ['.*', '.'], $regex); 147 } 148 $result = (bool)preg_match($regex, $haystack); 149 } 150 return $result; 151 } 152} 153