6536bdbc14e577b1f2b80dc05f5d43c72705d967
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Utility / StringUtility.php
1 <?php
2 namespace 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 */
20 class 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 }