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