StringUtil.php 2.7 KB

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