1<?php 2 3declare(strict_types=1); 4 5namespace Sabre\DAV; 6 7/** 8 * String utility. 9 * 10 * This class is mainly used to implement the 'text-match' filter, used by both 11 * the CalDAV calendar-query REPORT, and CardDAV addressbook-query REPORT. 12 * Because they both need it, it was decided to put it in Sabre\DAV instead. 13 * 14 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 15 * @author Evert Pot (http://evertpot.com/) 16 * @license http://sabre.io/license/ Modified BSD License 17 */ 18class StringUtil 19{ 20 /** 21 * Checks if a needle occurs in a haystack ;). 22 * 23 * @param string $haystack 24 * @param string $needle 25 * @param string $collation 26 * @param string $matchType 27 * 28 * @return bool 29 */ 30 public static function textMatch($haystack, $needle, $collation, $matchType = 'contains') 31 { 32 switch ($collation) { 33 case 'i;ascii-casemap': 34 // default strtolower takes locale into consideration 35 // we don't want this. 36 $haystack = str_replace(range('a', 'z'), range('A', 'Z'), $haystack); 37 $needle = str_replace(range('a', 'z'), range('A', 'Z'), $needle); 38 break; 39 40 case 'i;octet': 41 // Do nothing 42 break; 43 44 case 'i;unicode-casemap': 45 $haystack = mb_strtoupper($haystack, 'UTF-8'); 46 $needle = mb_strtoupper($needle, 'UTF-8'); 47 break; 48 49 default: 50 throw new Exception\BadRequest('Collation type: '.$collation.' is not supported'); 51 } 52 53 switch ($matchType) { 54 case 'contains': 55 return false !== strpos($haystack, $needle); 56 case 'equals': 57 return $haystack === $needle; 58 case 'starts-with': 59 return 0 === strpos($haystack, $needle); 60 case 'ends-with': 61 return strrpos($haystack, $needle) === strlen($haystack) - strlen($needle); 62 default: 63 throw new Exception\BadRequest('Match-type: '.$matchType.' is not supported'); 64 } 65 } 66 67 /** 68 * This method takes an input string, checks if it's not valid UTF-8 and 69 * attempts to convert it to UTF-8 if it's not. 70 * 71 * Note that currently this can only convert ISO-8859-1 to UTF-8 (latin-1), 72 * anything else will likely fail. 73 * 74 * @param string $input 75 * 76 * @return string 77 */ 78 public static function ensureUTF8($input) 79 { 80 $encoding = mb_detect_encoding($input, ['UTF-8', 'ISO-8859-1'], true); 81 82 if ('ISO-8859-1' === $encoding) { 83 return utf8_encode($input); 84 } else { 85 return $input; 86 } 87 } 88} 89