RSI helpers  0.1
RSI helpers
Str.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi;
4 
5 /**
6  * String helpers.
7  */
8 class Str{
9 
10  const TRANSFORM_LCFIRST = 'lcfirst';
11  const TRANSFORM_LOWER = 'lower';
12  const TRANSFORM_NL2BR = 'nl2br';
13  const TRANSFORM_NL2P = 'nl2p';
14  const TRANSFORM_NL2PBR = 'nl2pbr';
15  const TRANSFORM_TRIM = 'trim';
16  const TRANSFORM_UCFIRST = 'ucfirst';
17  const TRANSFORM_UCWORDS = 'ucwords';
18  const TRANSFORM_UPPER = 'upper';
19  const TRANSFORM_HTMLCHARS = 'htmlchars';
20  const TRANSFORM_URLIFY = 'urlify';
21  const TRANSFORM_URLENCODE = 'urlencode';
22 
23  const ATTRIBUTES_PATTERN = '\\s+(?<key>[\\w\\-]+)(?<value>=(\'([^\']*)\'|"([^"]*)"|(\\w+)))?';
24 
25  const PASSWORD_CHARS = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
26 
27  /**
28  * Returns literally 'true' or 'false'.
29  * @param bool $value
30  * @return string
31  */
32  public static function bool($value){
33  return $value ? 'true' : 'false';
34  }
35  /**
36  * Generate a random string.
37  * @param int $length Length of the resulting string.
38  * @param string $chars Characters to use. Ranges can be indicated as [{from}-{to}]. E.g. '[0-9][a-f]' for the hexadecimal
39  * range. Special cases: '*' all digits + letter (upper + lower case); '+': all digits + lower case letters; '@': all easy
40  * distinguishable characters (no 0/1/l/o).
41  * @return string
42  */
43  public static function random($length = 32,$chars = null){
44  switch($chars ?: '*'){
45  case '*': $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; break;
46  case '+': $chars = '0123456789abcdefghijklmnopqrstuvwxyz'; break;
47  case '@': $chars = '23456789abcdefghjklmnpqrstuvwxyz'; break;
48  default:
49  if(preg_match_all('/\\[(.)\\-(.)\\]/',$chars,$matches,PREG_SET_ORDER))
50  foreach($matches as list($full,$min,$max)) $chars = str_replace($full,implode(range($min,$max)),$chars);
51  }
52  $max = strlen($chars) - 1;
53  $result = '';
54  while($length--) $result .= $chars[random_int(0,$max)];
55  return $result;
56  }
57  /**
58  * Generate a code-name, based on the index.
59  * @param int $index
60  * @return string
61  */
62  public static function codeName($index){
63  $animals = require(__DIR__ . '/../../data/animals.php');
64  $letter = strtolower(substr($animal = $animals[$index % count($animals)],0,1));
65  $adjectives = array_values(array_filter(require(__DIR__ . '/../../data/adjectives.php'),function($adjective) use ($letter){
66  return strtolower(substr($adjective,0,1)) == $letter;
67  }));
68  return $adjectives[$index % count($adjectives)] . ' ' . $animal;
69  }
70  /**
71  * Transform an empty string to a null.
72  * @param string $str
73  * @return string
74  */
75  public static function nullify($str){
76  return $str === '' ? null : $str;
77  }
78  /**
79  * Remove accents from a string.
80  * @param string $str
81  * @return string
82  */
83  public static function normalize($str){
84  return str_replace(["'",'"'],'',iconv('UTF-8','ASCII//TRANSLIT//IGNORE',$str));
85  }
86  /**
87  * Transform a string to a URL-friendly version.
88  * @param string $str Original string.
89  * @param string $replace Character to replace non 'word' characters by.
90  * @return string URL-friendly string.
91  */
92  public static function urlify($str,$replace = '-'){
93  return strtolower(trim(preg_replace('/\\W+/',$replace,self::normalize($str)),$replace));
94  }
95  /**
96  * Replace ASCII emoji's by their Unicode equivalent.
97  * @param string $str String with ASCII emoji's (e.g. ';-)').
98  * @return string String with Unicode emoji's (e.g. '😉').
99  */
100  public static function emojify($str){
101  return strtr($str,require(__DIR__ . '/../../data/emoji.php'));
102  }
103  /**
104  * Remove leet-speak (1337 5p33k) from a string.
105  * @param string $str String with leet-speak characters.
106  * @param bool $upper Replace with uppercase letters.
107  * @return string String with leet-speak symbols replaced by their normal letter. This is near from perfect, since '13'
108  * could be 'LE' or 'B', '1' could be 'I' or 'L', etc).
109  */
110  public static function unleet($str,$upper = false){
111  $leet = require(__DIR__ . '/../../data/leet.php');
112  $length = 0;
113  foreach($leet as $chars) $length = max($length,max(array_map('strlen',$chars)));
114  do foreach($leet as $char => $chars) $str = str_replace(
115  array_filter($chars,function($char) use ($length){
116  return strlen($char) == $length;
117  }),
118  $upper ? $char : strtolower($char),
119  $str
120  );
121  while(--$length);
122  return $str;
123  }
124  /**
125  * Case insesitive string comparison.
126  * @param string $str1 First string.
127  * @param string $str2 Second string.
128  * @return Returns < 0 if str1 is less than str2, > 0 if str1 is greater than str2, and 0 if they are equal.
129  *
130  */
131  public static function icompare($str1,$str2){
132  return strcmp(mb_strtolower($str1),mb_strtolower($str2));
133  }
134  /**
135  * Pad function that defaults to left padding with zeros.
136  * @param string $str
137  * @param int $length
138  * @param string $pad
139  * @param int $type
140  * @return string
141  */
142  public static function pad($str,$length,$pad = '0',$type = STR_PAD_LEFT){
143  return str_pad($str,$length + strlen($str) - mb_strlen($str),$pad,$type);
144  }
145  /**
146  * Format a string.
147  * @param string $str Base string (without formatting).
148  * @param string $format Format, $replace characters are replaced with characters from the $str.
149  * @param string $pad Optional padding (to number of $replace characters in $format).
150  * @param int $type Padding type.
151  * @param string $replace Characters to replace in the $format.
152  * @return string Format with
153  */
154  public static function format($str,$format,$pad = null,$type = STR_PAD_LEFT,$replace = '*'){
155  if($pad !== null) $str = str_pad($str,substr_count($format,$replace),$pad,$type);
156  $result = '';
157  foreach(str_split($format) as $format) if($format === $replace){
158  if($str === '') break;
159  $result .= mb_substr($str,0,1);
160  $str = mb_substr($str,1);
161  }
162  else $result .= $format;
163  return $result;
164  }
165  /**
166  * Converts a delimited string to CamelCase.
167  * @param string $str Delimited string.
168  * @param string $delimiters Word delimiters.
169  * @return string
170  */
171  public static function camel($str,$delimiters = ' -_'){
172  return str_replace(str_split($delimiters),'',ucwords($str,$delimiters));
173  }
174  /**
175  * Converts a CamelCased string to snake_case.
176  * @param string $str CamelCased string.
177  * @param string $delimiter Delimiter to put between the words.
178  * @return string
179  */
180  public static function snake($str,$delimiter = '_'){
181  return strtolower(preg_replace('/([A-Z])([A-Z][a-z])/',"\$1$delimiter\$2",preg_replace('/([a-z\\d])([A-Z])/',"\$1$delimiter\$2",$str)));
182  }
183  /**
184  * Limit a string to a number of characters.
185  * @param string $str Original string.
186  * @param int $length Maximum length (including delimiter).
187  * @param bool $words Break at a word boundary.
188  * @param string $delimiter Character to indicate a limited string.
189  * @return string
190  */
191  public static function limit($str,$length,$words = false,$delimiter = '…'){
192  if(mb_strlen($str) > $length){
193  $str = mb_substr($str,0,$length - mb_strlen($delimiter));
194  if($words && ($i = strrpos($str,' '))) $str = substr($str,0,$i + 1);
195  $str .= $delimiter;
196  }
197  return $str;
198  }
199  /**
200  * Parse a string into variables.
201  * Basicly parse_str() but with a returned array instead of by reference.
202  * @param string $str
203  * @return array
204  */
205  public static function parse($str){
206  parse_str($str,$data);
207  return $data;
208  }
209  /**
210  * Return part of a string until a needle. Shorten the string including the needle.
211  * @param string $haystack String to search in.
212  * @param string $needle Needle to look for (not found = return string until end).
213  * @return string Part of string until the needle.
214  */
215  public static function strip(&$haystack,$needle){
216  $result = substr($haystack,0,$i = strpos($haystack . $needle,$needle));
217  $haystack = substr($haystack,$i + 1);
218  return $result;
219  }
220  /**
221  * Return part of a string after a needle. Shorten the string including the needle.
222  * @param string $haystack String to search in.
223  * @param string $needle Needle to look for (not found = return string until end).
224  * @return string Part of string after the needle (false if needle not found).
225  */
226  public static function pop(&$haystack,$needle){
227  $i = strrpos($haystack,$needle);
228  if($i === false) return false;
229  $result = substr($haystack,$i + 1);
230  $haystack = substr($haystack,0,$i);
231  return $result;
232  }
233  /**
234  * Return part of a string until a needle.
235  * @param string $haystack String to search in.
236  * @param string $needle Needle to look for.
237  * @param int $index Number of parts/needles to skip.
238  * @return string Part of string until the needle (false = index not found).
239  */
240  public static function part($haystack,$needle,$index = 0){
241  $parts = explode($needle,$haystack);
242  return $index < count($parts) ? $parts[$index] : false;
243  }
244  /**
245  * Insert a string at a certain position in another string.
246  * @param string $str String to insert to.
247  * @param string $insert String to insert into $str.
248  * @param int $position Position to insert at (negative = relative to end).
249  * @param int $length Length of the part to replace with the insertion.
250  * @return string
251  */
252  public static function insert($str,$insert,$position,$length = 0){
253  return substr($str,0,$position) . $insert . substr($str,$position + $length);
254  }
255  /**
256  * Remove optinal quotes from a string.
257  * Quotes are only removed if they appear on both ends of the string.
258  * @param string $str String to remove quotes from.
259  * @param array $quotes Possible quote characters.
260  * @return string String without quotes.
261  */
262  public static function stripQuotes($str,$quotes = ["'",'"']){
263  return in_array($quote = substr($str,0,1),$quotes) && (substr($str,-1) == $quote) ? substr($str,1,-1) : $str;
264  }
265  /**
266  * Wrap a string into multiple lines (better wordwrap()).
267  * @param string $str String to wrap.
268  * @param int $width Maximum width.
269  * @return array Wrapped lines.
270  */
271  public static function wrap($str,$width){
272  $lines = [];
273  foreach(explode("\n",strtr($str,["\r" => '',"\t" => ' '])) as $line) while($line){
274  if(($length = mb_strlen($line)) > $width){
275  preg_match("/^.{0,$width}\\s/u",$line,$space);
276  preg_match('/^.{0,' . ($width - 1) . '}-/u',$line,$hyphen);
277  $length = ($space || $hyphen) ? max($space ? mb_strlen($space[0]) : 0,$hyphen ? mb_strlen($hyphen[0]) : 0) : $width;
278  }
279  $lines[] = rtrim(mb_substr($line,0,$length));
280  $line = mb_substr($line,$length);
281  }
282  return $lines;
283  }
284  /**
285  * Replace all newlines with HTML paragraph tags
286  * @param string $str String to format.
287  * @return string String with paragraphs (null on effective empty string).
288  */
289  public static function nl2p($str){
290  return ($str = trim($str)) ? '<p>' . preg_replace('/\\s*\\n\\s*/','</p><p>',str_replace("\r",'',$str)) . '</p>' : null;
291  }
292  /**
293  * Replace all multi newlines with HTML paragraph tags, and single newlines with line breaks.
294  * @param string $str String to format.
295  * @return string String with paragraphs and line breaks (null on effective empty string).
296  */
297  public static function nl2pbr($str){
298  return ($str = trim($str)) ? '<p>' . nl2br(preg_replace('/\\s*\\n\\s*\\n\\s*/','</p><p>',str_replace("\r",'',$str))) . '</p>' : null;
299  }
300  /**
301  * Transforms a string according to a certain function.
302  * @param string $str String to format.
303  * @param string|array $methods One or more format function(s).
304  * @param int $count Number of format functions applied (> 0 = ok; 0 = unkown function).
305  * @return string Tranformed string.
306  */
307  public static function transform($str,$methods,&$count = null){
308  if(!is_array($methods)) $methods = [$methods];
309  $count = count($methods);
310  foreach($methods as $method) switch($method){
311  case self::TRANSFORM_LCFIRST: $str = lcfirst($str); break;
312  case self::TRANSFORM_LOWER: $str = strtolower($str); break;
313  case self::TRANSFORM_NL2BR: $str = nl2br($str); break;
314  case self::TRANSFORM_NL2P: $str = nl2p($str); break;
315  case self::TRANSFORM_NL2PBR: $str = nl2pbr($str); break;
316  case self::TRANSFORM_TRIM: $str = trim($str); break;
317  case self::TRANSFORM_UCFIRST: $str = ucfirst($str); break;
318  case self::TRANSFORM_UCWORDS: $str = ucwords($str); break;
319  case self::TRANSFORM_UPPER: $str = strtoupper($str); break;
320  case self::TRANSFORM_HTMLCHARS: $str = htmlspecialchars($str); break;
321  case self::TRANSFORM_URLIFY: $str = self::urlify($str); break;
322  case self::TRANSFORM_URLENCODE: $str = rawurlencode($str); break;
323  default: $count--;
324  }
325  return $str;
326  }
327  /**
328  * Check if a string starts with a specific value.
329  * @param string $haystack String to search in.
330  * @param string $needle Value to look for at the start of the haystack.
331  * @result bool True if the haystack starts with the needle.
332  */
333  public static function startsWith($haystack,$needle){
334  return substr($haystack,0,strlen($needle)) == $needle;
335  }
336  /**
337  * Make sure a string starts with a specific value.
338  * @param string $haystack Base string.
339  * @param string $needle Value to check for at the start of the haystack.
340  * @return string Base string with the needle added if not present.
341  */
342  public static function startWith($haystack,$needle){
343  return self::startsWith($haystack,$needle) ? $haystack : $needle . $haystack;
344  }
345  /**
346  * Check if a string ends with a specific value.
347  * @param string $haystack String to search in.
348  * @param string $needle Value to look for at the end of the haystack.
349  * @result bool True if the haystack ends with the needle.
350  */
351  public static function endsWith($haystack,$needle){
352  return substr($haystack,-strlen($needle)) == $needle;
353  }
354  /**
355  * Make sure a string ends with a specific value.
356  * @param string $haystack Base string.
357  * @param string $needle Value to check for at the end of the haystack.
358  * @return string Base string with the needle added if not present.
359  */
360  public static function endWith($haystack,$needle){
361  return self::endsWith($haystack,$needle) ? $haystack : $haystack . $needle;
362  }
363  /**
364  * Numeric detection.
365  * Works only on decimal numbers, plus signs and exponential parts are not allowed.
366  * @param mixed $value Value to check.
367  * @return bool True if the value is a numeric.
368  */
369  public static function numeric($value){
370  return is_string($value) && preg_match('/^(\\-?[1-9]\\d*|0)(\\.\\d+)?$/',$value);
371  }
372  /**
373  * Evaluate an operator between a value and a reference value.
374  * Besides the usual '==', '!=', '>', '>=', '<', '<=', en '%' operators there are also some specific operators::
375  * - '*-' : Reference starts with the value.
376  * - '*-' : Reference ends with the value.
377  * - '*' : Reference contains the value.
378  * - '//' : Reference matches the regular expression in the value.
379  * @param string $ref Reference value. The value to look at.
380  * @param string $operator Operator.
381  * @param string $value Value sought after in the reference.
382  * @param bool $default Default result (unknown operator).
383  * @return bool True if the value matches the reference according to the operator.
384  */
385  public static function operator($ref,$operator,$value,$default = false){
386  switch($operator){
387  case '==': return $ref == $value;
388  case '!=': return $ref != $value;
389  case '>': return $ref > $value;
390  case '>=': return $ref >= $value;
391  case '<': return $ref < $value;
392  case '<=': return $ref <= $value;
393  case '%': return $ref % $value;
394  case '=%': return $ref % $value == 0;
395  case '*-': return self::startsWith($ref,$value);
396  case '-*': return self::endsWith($ref,$value);
397  case '*': return strpos($ref,$value) !== false;
398  case '//': return preg_match(substr($value,0,1) == '/' ? $value : '/' . $value . '/',$ref);
399  }
400  return $default;
401  }
402  /**
403  * Convert an array to a list.
404  * @param array $array Array with list items.
405  * @param string $last_delimiter Delimiter for the last item (same as delimiter when empty).
406  * @param string $delimiter Delimiter for the items.
407  * @return string
408  */
409  public static function implode($array,$last_delimiter = null,$delimiter = ', '){
410  $last = array_pop($array);
411  return $array ? implode($delimiter,$array) . ($last_delimiter ?: $delimiter) . $last : $last;
412  }
413  /**
414  * Show ranges from a numerical array.
415  * For example [1,2,3,5,6,8,9,10] becomes '1 - 3, 5, 6, 8 - 10'.
416  * @param array $array Array with numbers.
417  * @param string $delimiter Delimiter to use between ranges.
418  * @param string $separator Seperator to use between boundaries of a range.
419  * @return string
420  */
421  public static function ranges($array,$delimiter = ', ',$separator = ' - '){
422  $result = [];
423  foreach(Record::ranges($array) as $start => $end)
424  if($end > $start + 1) $result[] = $start . $separator . $end;
425  else{
426  $result[] = $start;
427  if($start != $end) $result[] = $end;
428  }
429  return implode($delimiter,$result);
430  }
431  /**
432  * Replace date tags in a string.
433  * @param string $str String with date tags.
434  * @param int $time Timestamp to use (empty = now).
435  * @param string $open Open tag.
436  * @param string $close Close tag.
437  * @return string String with tags replaced.
438  */
439  public static function replaceDate($str,$time = null,$open = '[',$close = ']'){
440  if(preg_match_all('/' . preg_quote($open,'/') . '(\w+)' . preg_quote($close,'/') . '/',$str,$matches,PREG_SET_ORDER)){
441  if(!$time) $time = time();
442  foreach($matches as $match) $str = str_replace($match[0],date($match[1],$time),$str);
443  }
444  return $str;
445  }
446  /**
447  * Extract attributes from a string.
448  * @param string $str String with attributes.
449  * @return array Attributes (assoc. array).
450  */
451  public static function attributes($str){
452  $attribs = [];
453  if($str && preg_match_all('/' . self::ATTRIBUTES_PATTERN . '/',$str,$matches,PREG_SET_ORDER)) foreach($matches as $match)
454  $attribs[$match['key']] = array_key_exists('value',$match) ? html_entity_decode(array_pop($match)) : true;
455  return $attribs;
456  }
457 
458 }
static emojify($str)
Replace ASCII emoji&#39;s by their Unicode equivalent.
Definition: Str.php:100
static parse($str)
Parse a string into variables.
Definition: Str.php:205
static urlify($str, $replace='-')
Transform a string to a URL-friendly version.
Definition: Str.php:92
static startsWith($haystack, $needle)
Check if a string starts with a specific value.
Definition: Str.php:333
static strip(&$haystack, $needle)
Return part of a string until a needle.
Definition: Str.php:215
static nl2p($str)
Replace all newlines with HTML paragraph tags.
Definition: Str.php:289
String helpers.
Definition: Str.php:8
static nl2pbr($str)
Replace all multi newlines with HTML paragraph tags, and single newlines with line breaks...
Definition: Str.php:297
static random($length=32, $chars=null)
Generate a random string.
Definition: Str.php:43
static limit($str, $length, $words=false, $delimiter='…')
Limit a string to a number of characters.
Definition: Str.php:191
static codeName($index)
Generate a code-name, based on the index.
Definition: Str.php:62
static startWith($haystack, $needle)
Make sure a string starts with a specific value.
Definition: Str.php:342
static part($haystack, $needle, $index=0)
Return part of a string until a needle.
Definition: Str.php:240
static ranges($array, $delimiter=', ', $separator=' - ')
Show ranges from a numerical array.
Definition: Str.php:421
static nullify($str)
Transform an empty string to a null.
Definition: Str.php:75
static endsWith($haystack, $needle)
Check if a string ends with a specific value.
Definition: Str.php:351
static bool($value)
Returns literally &#39;true&#39; or &#39;false&#39;.
Definition: Str.php:32
static format($str, $format, $pad=null, $type=STR_PAD_LEFT, $replace=' *')
Format a string.
Definition: Str.php:154
static normalize($str)
Remove accents from a string.
Definition: Str.php:83
static pop(&$haystack, $needle)
Return part of a string after a needle.
Definition: Str.php:226
static wrap($str, $width)
Wrap a string into multiple lines (better wordwrap()).
Definition: Str.php:271
static endWith($haystack, $needle)
Make sure a string ends with a specific value.
Definition: Str.php:360
static pad($str, $length, $pad='0', $type=STR_PAD_LEFT)
Pad function that defaults to left padding with zeros.
Definition: Str.php:142
Definition: Color.php:3
static operator($ref, $operator,$value, $default=false)
Evaluate an operator between a value and a reference value.
Definition: Str.php:385
static stripQuotes($str, $quotes=["'",'"'])
Remove optinal quotes from a string.
Definition: Str.php:262
static camel($str, $delimiters=' -_')
Converts a delimited string to CamelCase.
Definition: Str.php:171
static snake($str, $delimiter='_')
Converts a CamelCased string to snake_case.
Definition: Str.php:180
static transform($str, $methods, &$count=null)
Transforms a string according to a certain function.
Definition: Str.php:307
static numeric($value)
Numeric detection.
Definition: Str.php:369
static insert($str, $insert, $position, $length=0)
Insert a string at a certain position in another string.
Definition: Str.php:252
static implode($array, $last_delimiter=null, $delimiter=', ')
Convert an array to a list.
Definition: Str.php:409
static attributes($str)
Extract attributes from a string.
Definition: Str.php:451
static unleet($str, $upper=false)
Remove leet-speak (1337 5p33k) from a string.
Definition: Str.php:110
static replaceDate($str, $time=null, $open='[', $close=']')
Replace date tags in a string.
Definition: Str.php:439
static icompare($str1, $str2)
Case insesitive string comparison.
Definition: Str.php:131