CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.1 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.1
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
    • Network
      • Email
      • Http
    • Routing
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • I18n
  • L10n
  • Multibyte

Functions

  • mb_encode_mimeheader
  • mb_stripos
  • mb_stristr
  • mb_strlen
  • mb_strpos
  • mb_strrchr
  • mb_strrichr
  • mb_strripos
  • mb_strrpos
  • mb_strstr
  • mb_strtolower
  • mb_strtoupper
  • mb_substr
  • mb_substr_count
   1: <?php
   2: /**
   3:  * Multibyte handling methods.
   4:  *
   5:  *
   6:  * PHP 5
   7:  *
   8:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
   9:  * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  10:  *
  11:  * Licensed under The MIT License
  12:  * Redistributions of files must retain the above copyright notice.
  13:  *
  14:  * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  15:  * @link          http://cakephp.org CakePHP(tm) Project
  16:  * @package       Cake.I18n
  17:  * @since         CakePHP(tm) v 1.2.0.6833
  18:  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
  19:  */
  20: 
  21: if (!function_exists('mb_stripos')) {
  22: 
  23: /**
  24:  * Find position of first occurrence of a case-insensitive string.
  25:  *
  26:  * @param string $haystack The string from which to get the position of the first occurrence of $needle.
  27:  * @param string $needle The string to find in $haystack.
  28:  * @param integer $offset The position in $haystack to start searching.
  29:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
  30:  * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string, or false
  31:  *    if $needle is not found.
  32:  */
  33:     function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) {
  34:         return Multibyte::stripos($haystack, $needle, $offset);
  35:     }
  36: 
  37: }
  38: 
  39: if (!function_exists('mb_stristr')) {
  40: 
  41: /**
  42:  * Finds first occurrence of a string within another, case insensitive.
  43:  *
  44:  * @param string $haystack The string from which to get the first occurrence of $needle.
  45:  * @param string $needle The string to find in $haystack.
  46:  * @param boolean $part Determines which portion of $haystack this function returns.
  47:  *    If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
  48:  *    If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
  49:  *    Default value is false.
  50:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
  51:  * @return string|boolean The portion of $haystack, or false if $needle is not found.
  52:  */
  53:     function mb_stristr($haystack, $needle, $part = false, $encoding = null) {
  54:         return Multibyte::stristr($haystack, $needle, $part);
  55:     }
  56: 
  57: }
  58: 
  59: if (!function_exists('mb_strlen')) {
  60: 
  61: /**
  62:  * Get string length.
  63:  *
  64:  * @param string $string The string being checked for length.
  65:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
  66:  * @return integer The number of characters in string $string having character encoding encoding.
  67:  *    A multi-byte character is counted as 1.
  68:  */
  69:     function mb_strlen($string, $encoding = null) {
  70:         return Multibyte::strlen($string);
  71:     }
  72: 
  73: }
  74: 
  75: if (!function_exists('mb_strpos')) {
  76: 
  77: /**
  78:  * Find position of first occurrence of a string.
  79:  *
  80:  * @param string $haystack The string being checked.
  81:  * @param string $needle The position counted from the beginning of haystack.
  82:  * @param integer $offset The search offset. If it is not specified, 0 is used.
  83:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
  84:  * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string.
  85:  *    If $needle is not found, it returns false.
  86:  */
  87:     function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) {
  88:         return Multibyte::strpos($haystack, $needle, $offset);
  89:     }
  90: 
  91: }
  92: 
  93: if (!function_exists('mb_strrchr')) {
  94: 
  95: /**
  96:  * Finds the last occurrence of a character in a string within another.
  97:  *
  98:  * @param string $haystack The string from which to get the last occurrence of $needle.
  99:  * @param string $needle The string to find in $haystack.
 100:  * @param boolean $part Determines which portion of $haystack this function returns.
 101:  *    If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
 102:  *    If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
 103:  *    Default value is false.
 104:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 105:  * @return string|boolean The portion of $haystack. or false if $needle is not found.
 106:  */
 107:     function mb_strrchr($haystack, $needle, $part = false, $encoding = null) {
 108:         return Multibyte::strrchr($haystack, $needle, $part);
 109:     }
 110: 
 111: }
 112: 
 113: if (!function_exists('mb_strrichr')) {
 114: 
 115: /**
 116:  * Finds the last occurrence of a character in a string within another, case insensitive.
 117:  *
 118:  * @param string $haystack The string from which to get the last occurrence of $needle.
 119:  * @param string $needle The string to find in $haystack.
 120:  * @param boolean $part Determines which portion of $haystack this function returns.
 121:  *    If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
 122:  *    If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
 123:  *    Default value is false.
 124:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 125:  * @return string|boolean The portion of $haystack. or false if $needle is not found.
 126:  */
 127:     function mb_strrichr($haystack, $needle, $part = false, $encoding = null) {
 128:         return Multibyte::strrichr($haystack, $needle, $part);
 129:     }
 130: 
 131: }
 132: 
 133: if (!function_exists('mb_strripos')) {
 134: 
 135: /**
 136:  * Finds position of last occurrence of a string within another, case insensitive
 137:  *
 138:  * @param string $haystack The string from which to get the position of the last occurrence of $needle.
 139:  * @param string $needle The string to find in $haystack.
 140:  * @param integer $offset The position in $haystack to start searching.
 141:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 142:  * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string,
 143:  *    or false if $needle is not found.
 144:  */
 145:     function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) {
 146:         return Multibyte::strripos($haystack, $needle, $offset);
 147:     }
 148: 
 149: }
 150: 
 151: if (!function_exists('mb_strrpos')) {
 152: 
 153: /**
 154:  * Find position of last occurrence of a string in a string.
 155:  *
 156:  * @param string $haystack The string being checked, for the last occurrence of $needle.
 157:  * @param string $needle The string to find in $haystack.
 158:  * @param integer $offset May be specified to begin searching an arbitrary number of characters into the string.
 159:  *    Negative values will stop searching at an arbitrary point prior to the end of the string.
 160:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 161:  * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string.
 162:  *    If $needle is not found, it returns false.
 163:  */
 164:     function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) {
 165:         return Multibyte::strrpos($haystack, $needle, $offset);
 166:     }
 167: 
 168: }
 169: 
 170: if (!function_exists('mb_strstr')) {
 171: 
 172: /**
 173:  * Finds first occurrence of a string within another
 174:  *
 175:  * @param string $haystack The string from which to get the first occurrence of $needle.
 176:  * @param string $needle The string to find in $haystack
 177:  * @param boolean $part Determines which portion of $haystack this function returns.
 178:  *    If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
 179:  *    If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
 180:  *    Default value is FALSE.
 181:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 182:  * @return string|boolean The portion of $haystack, or true if $needle is not found.
 183:  */
 184:     function mb_strstr($haystack, $needle, $part = false, $encoding = null) {
 185:         return Multibyte::strstr($haystack, $needle, $part);
 186:     }
 187: 
 188: }
 189: 
 190: if (!function_exists('mb_strtolower')) {
 191: 
 192: /**
 193:  * Make a string lowercase
 194:  *
 195:  * @param string $string The string being lowercased.
 196:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 197:  * @return string with all alphabetic characters converted to lowercase.
 198:  */
 199:     function mb_strtolower($string, $encoding = null) {
 200:         return Multibyte::strtolower($string);
 201:     }
 202: 
 203: }
 204: 
 205: if (!function_exists('mb_strtoupper')) {
 206: 
 207: /**
 208:  * Make a string uppercase
 209:  *
 210:  * @param string $string The string being uppercased.
 211:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 212:  * @return string with all alphabetic characters converted to uppercase.
 213:  */
 214:     function mb_strtoupper($string, $encoding = null) {
 215:         return Multibyte::strtoupper($string);
 216:     }
 217: 
 218: }
 219: 
 220: if (!function_exists('mb_substr_count')) {
 221: 
 222: /**
 223:  * Count the number of substring occurrences
 224:  *
 225:  * @param string $haystack The string being checked.
 226:  * @param string $needle The string being found.
 227:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 228:  * @return integer The number of times the $needle substring occurs in the $haystack string.
 229:  */
 230:     function mb_substr_count($haystack, $needle, $encoding = null) {
 231:         return Multibyte::substrCount($haystack, $needle);
 232:     }
 233: 
 234: }
 235: 
 236: if (!function_exists('mb_substr')) {
 237: 
 238: /**
 239:  * Get part of string
 240:  *
 241:  * @param string $string The string being checked.
 242:  * @param integer $start The first position used in $string.
 243:  * @param integer $length The maximum length of the returned string.
 244:  * @param string $encoding Character encoding name to use. If it is omitted, internal character encoding is used.
 245:  * @return string The portion of $string specified by the $string and $length parameters.
 246:  */
 247:     function mb_substr($string, $start, $length = null, $encoding = null) {
 248:         return Multibyte::substr($string, $start, $length);
 249:     }
 250: 
 251: }
 252: 
 253: if (!function_exists('mb_encode_mimeheader')) {
 254: 
 255: /**
 256:  * Encode string for MIME header
 257:  *
 258:  * @param string $str The string being encoded
 259:  * @param string $charset specifies the name of the character set in which str is represented in.
 260:  *    The default value is determined by the current NLS setting (mbstring.language).
 261:  * @param string $transfer_encoding specifies the scheme of MIME encoding.
 262:  *    It should be either "B" (Base64) or "Q" (Quoted-Printable). Falls back to "B" if not given.
 263:  * @param string $linefeed specifies the EOL (end-of-line) marker with which
 264:  *    mb_encode_mimeheader() performs line-folding
 265:  *    (a ยป RFC term, the act of breaking a line longer than a certain length into multiple lines.
 266:  *    The length is currently hard-coded to 74 characters). Falls back to "\r\n" (CRLF) if not given.
 267:  * @param integer $indent [definition unknown and appears to have no affect]
 268:  * @return string A converted version of the string represented in ASCII.
 269:  */
 270:     function mb_encode_mimeheader($str, $charset = 'UTF-8', $transferEncoding = 'B', $linefeed = "\r\n", $indent = 1) {
 271:         return Multibyte::mimeEncode($str, $charset, $linefeed);
 272:     }
 273: 
 274: }
 275: 
 276: /**
 277:  * Multibyte handling methods.
 278:  *
 279:  * @package       Cake.I18n
 280:  */
 281: class Multibyte {
 282: 
 283: /**
 284:  *  Holds the case folding values
 285:  *
 286:  * @var array
 287:  */
 288:     protected static $_caseFold = array();
 289: 
 290: /**
 291:  * Holds an array of Unicode code point ranges
 292:  *
 293:  * @var array
 294:  */
 295:     protected static $_codeRange = array();
 296: 
 297: /**
 298:  * Holds the current code point range
 299:  *
 300:  * @var string
 301:  */
 302:     protected static $_table = null;
 303: 
 304: /**
 305:  * Converts a multibyte character string
 306:  * to the decimal value of the character
 307:  *
 308:  * @param string $string
 309:  * @return array
 310:  */
 311:     public static function utf8($string) {
 312:         $map = array();
 313: 
 314:         $values = array();
 315:         $find = 1;
 316:         $length = strlen($string);
 317: 
 318:         for ($i = 0; $i < $length; $i++) {
 319:             $value = ord($string[$i]);
 320: 
 321:             if ($value < 128) {
 322:                 $map[] = $value;
 323:             } else {
 324:                 if (empty($values)) {
 325:                     $find = ($value < 224) ? 2 : 3;
 326:                 }
 327:                 $values[] = $value;
 328: 
 329:                 if (count($values) === $find) {
 330:                     if ($find == 3) {
 331:                         $map[] = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64);
 332:                     } else {
 333:                         $map[] = (($values[0] % 32) * 64) + ($values[1] % 64);
 334:                     }
 335:                     $values = array();
 336:                     $find = 1;
 337:                 }
 338:             }
 339:         }
 340:         return $map;
 341:     }
 342: 
 343: /**
 344:  * Converts the decimal value of a multibyte character string
 345:  * to a string
 346:  *
 347:  * @param array $array
 348:  * @return string
 349:  */
 350:     public static function ascii($array) {
 351:         $ascii = '';
 352: 
 353:         foreach ($array as $utf8) {
 354:             if ($utf8 < 128) {
 355:                 $ascii .= chr($utf8);
 356:             } elseif ($utf8 < 2048) {
 357:                 $ascii .= chr(192 + (($utf8 - ($utf8 % 64)) / 64));
 358:                 $ascii .= chr(128 + ($utf8 % 64));
 359:             } else {
 360:                 $ascii .= chr(224 + (($utf8 - ($utf8 % 4096)) / 4096));
 361:                 $ascii .= chr(128 + ((($utf8 % 4096) - ($utf8 % 64)) / 64));
 362:                 $ascii .= chr(128 + ($utf8 % 64));
 363:             }
 364:         }
 365:         return $ascii;
 366:     }
 367: 
 368: /**
 369:  * Find position of first occurrence of a case-insensitive string.
 370:  *
 371:  * @param string $haystack The string from which to get the position of the first occurrence of $needle.
 372:  * @param string $needle The string to find in $haystack.
 373:  * @param integer $offset The position in $haystack to start searching.
 374:  * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string,
 375:  *    or false if $needle is not found.
 376:  */
 377:     public static function stripos($haystack, $needle, $offset = 0) {
 378:         if (Multibyte::checkMultibyte($haystack)) {
 379:             $haystack = Multibyte::strtoupper($haystack);
 380:             $needle = Multibyte::strtoupper($needle);
 381:             return Multibyte::strpos($haystack, $needle, $offset);
 382:         }
 383:         return stripos($haystack, $needle, $offset);
 384:     }
 385: 
 386: /**
 387:  * Finds first occurrence of a string within another, case insensitive.
 388:  *
 389:  * @param string $haystack The string from which to get the first occurrence of $needle.
 390:  * @param string $needle The string to find in $haystack.
 391:  * @param boolean $part Determines which portion of $haystack this function returns.
 392:  *    If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
 393:  *    If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
 394:  *    Default value is false.
 395:  * @return integer|boolean The portion of $haystack, or false if $needle is not found.
 396:  */
 397:     public static function stristr($haystack, $needle, $part = false) {
 398:         $php = (PHP_VERSION < 5.3);
 399: 
 400:         if (($php && $part) || Multibyte::checkMultibyte($haystack)) {
 401:             $check = Multibyte::strtoupper($haystack);
 402:             $check = Multibyte::utf8($check);
 403:             $found = false;
 404: 
 405:             $haystack = Multibyte::utf8($haystack);
 406:             $haystackCount = count($haystack);
 407: 
 408:             $needle = Multibyte::strtoupper($needle);
 409:             $needle = Multibyte::utf8($needle);
 410:             $needleCount = count($needle);
 411: 
 412:             $parts = array();
 413:             $position = 0;
 414: 
 415:             while (($found === false) && ($position < $haystackCount)) {
 416:                 if (isset($needle[0]) && $needle[0] === $check[$position]) {
 417:                     for ($i = 1; $i < $needleCount; $i++) {
 418:                         if ($needle[$i] !== $check[$position + $i]) {
 419:                             break;
 420:                         }
 421:                     }
 422:                     if ($i === $needleCount) {
 423:                         $found = true;
 424:                     }
 425:                 }
 426:                 if (!$found) {
 427:                     $parts[] = $haystack[$position];
 428:                     unset($haystack[$position]);
 429:                 }
 430:                 $position++;
 431:             }
 432: 
 433:             if ($found && $part && !empty($parts)) {
 434:                 return Multibyte::ascii($parts);
 435:             } elseif ($found && !empty($haystack)) {
 436:                 return Multibyte::ascii($haystack);
 437:             }
 438:             return false;
 439:         }
 440: 
 441:         if (!$php) {
 442:             return stristr($haystack, $needle, $part);
 443:         }
 444:         return stristr($haystack, $needle);
 445:     }
 446: 
 447: /**
 448:  * Get string length.
 449:  *
 450:  * @param string $string The string being checked for length.
 451:  * @return integer The number of characters in string $string
 452:  */
 453:     public static function strlen($string) {
 454:         if (Multibyte::checkMultibyte($string)) {
 455:             $string = Multibyte::utf8($string);
 456:             return count($string);
 457:         }
 458:         return strlen($string);
 459:     }
 460: 
 461: /**
 462:  * Find position of first occurrence of a string.
 463:  *
 464:  * @param string $haystack The string being checked.
 465:  * @param string $needle The position counted from the beginning of haystack.
 466:  * @param integer $offset The search offset. If it is not specified, 0 is used.
 467:  * @return integer|boolean The numeric position of the first occurrence of $needle in the $haystack string.
 468:  *    If $needle is not found, it returns false.
 469:  */
 470:     public static function strpos($haystack, $needle, $offset = 0) {
 471:         if (Multibyte::checkMultibyte($haystack)) {
 472:             $found = false;
 473: 
 474:             $haystack = Multibyte::utf8($haystack);
 475:             $haystackCount = count($haystack);
 476: 
 477:             $needle = Multibyte::utf8($needle);
 478:             $needleCount = count($needle);
 479: 
 480:             $position = $offset;
 481: 
 482:             while (($found === false) && ($position < $haystackCount)) {
 483:                 if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
 484:                     for ($i = 1; $i < $needleCount; $i++) {
 485:                         if ($needle[$i] !== $haystack[$position + $i]) {
 486:                             break;
 487:                         }
 488:                     }
 489:                     if ($i === $needleCount) {
 490:                         $found = true;
 491:                         $position--;
 492:                     }
 493:                 }
 494:                 $position++;
 495:             }
 496:             if ($found) {
 497:                 return $position;
 498:             }
 499:             return false;
 500:         }
 501:         return strpos($haystack, $needle, $offset);
 502:     }
 503: 
 504: /**
 505:  * Finds the last occurrence of a character in a string within another.
 506:  *
 507:  * @param string $haystack The string from which to get the last occurrence of $needle.
 508:  * @param string $needle The string to find in $haystack.
 509:  * @param boolean $part Determines which portion of $haystack this function returns.
 510:  *    If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
 511:  *    If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
 512:  *    Default value is false.
 513:  * @return string|boolean The portion of $haystack. or false if $needle is not found.
 514:  */
 515:     public static function strrchr($haystack, $needle, $part = false) {
 516:         $check = Multibyte::utf8($haystack);
 517:         $found = false;
 518: 
 519:         $haystack = Multibyte::utf8($haystack);
 520:         $haystackCount = count($haystack);
 521: 
 522:         $matches = array_count_values($check);
 523: 
 524:         $needle = Multibyte::utf8($needle);
 525:         $needleCount = count($needle);
 526: 
 527:         $parts = array();
 528:         $position = 0;
 529: 
 530:         while (($found === false) && ($position < $haystackCount)) {
 531:             if (isset($needle[0]) && $needle[0] === $check[$position]) {
 532:                 for ($i = 1; $i < $needleCount; $i++) {
 533:                     if ($needle[$i] !== $check[$position + $i]) {
 534:                         if ($needle[$i] === $check[($position + $i) - 1]) {
 535:                             $found = true;
 536:                         }
 537:                         unset($parts[$position - 1]);
 538:                         $haystack = array_merge(array($haystack[$position]), $haystack);
 539:                         break;
 540:                     }
 541:                 }
 542:                 if (isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
 543:                     $matches[$needle[0]] = $matches[$needle[0]] - 1;
 544:                 } elseif ($i === $needleCount) {
 545:                     $found = true;
 546:                 }
 547:             }
 548: 
 549:             if (!$found && isset($haystack[$position])) {
 550:                 $parts[] = $haystack[$position];
 551:                 unset($haystack[$position]);
 552:             }
 553:             $position++;
 554:         }
 555: 
 556:         if ($found && $part && !empty($parts)) {
 557:             return Multibyte::ascii($parts);
 558:         } elseif ($found && !empty($haystack)) {
 559:             return Multibyte::ascii($haystack);
 560:         }
 561:         return false;
 562:     }
 563: 
 564: /**
 565:  * Finds the last occurrence of a character in a string within another, case insensitive.
 566:  *
 567:  * @param string $haystack The string from which to get the last occurrence of $needle.
 568:  * @param string $needle The string to find in $haystack.
 569:  * @param boolean $part Determines which portion of $haystack this function returns.
 570:  *    If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
 571:  *    If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
 572:  *    Default value is false.
 573:  * @return string|boolean The portion of $haystack. or false if $needle is not found.
 574:  */
 575:     public static function strrichr($haystack, $needle, $part = false) {
 576:         $check = Multibyte::strtoupper($haystack);
 577:         $check = Multibyte::utf8($check);
 578:         $found = false;
 579: 
 580:         $haystack = Multibyte::utf8($haystack);
 581:         $haystackCount = count($haystack);
 582: 
 583:         $matches = array_count_values($check);
 584: 
 585:         $needle = Multibyte::strtoupper($needle);
 586:         $needle = Multibyte::utf8($needle);
 587:         $needleCount = count($needle);
 588: 
 589:         $parts = array();
 590:         $position = 0;
 591: 
 592:         while (($found === false) && ($position < $haystackCount)) {
 593:             if (isset($needle[0]) && $needle[0] === $check[$position]) {
 594:                 for ($i = 1; $i < $needleCount; $i++) {
 595:                     if ($needle[$i] !== $check[$position + $i]) {
 596:                         if ($needle[$i] === $check[($position + $i) - 1]) {
 597:                             $found = true;
 598:                         }
 599:                         unset($parts[$position - 1]);
 600:                         $haystack = array_merge(array($haystack[$position]), $haystack);
 601:                         break;
 602:                     }
 603:                 }
 604:                 if (isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
 605:                     $matches[$needle[0]] = $matches[$needle[0]] - 1;
 606:                 } elseif ($i === $needleCount) {
 607:                     $found = true;
 608:                 }
 609:             }
 610: 
 611:             if (!$found && isset($haystack[$position])) {
 612:                 $parts[] = $haystack[$position];
 613:                 unset($haystack[$position]);
 614:             }
 615:             $position++;
 616:         }
 617: 
 618:         if ($found && $part && !empty($parts)) {
 619:             return Multibyte::ascii($parts);
 620:         } elseif ($found && !empty($haystack)) {
 621:             return Multibyte::ascii($haystack);
 622:         }
 623:         return false;
 624:     }
 625: 
 626: /**
 627:  * Finds position of last occurrence of a string within another, case insensitive
 628:  *
 629:  * @param string $haystack The string from which to get the position of the last occurrence of $needle.
 630:  * @param string $needle The string to find in $haystack.
 631:  * @param integer $offset The position in $haystack to start searching.
 632:  * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string,
 633:  *    or false if $needle is not found.
 634:  */
 635:     public static function strripos($haystack, $needle, $offset = 0) {
 636:         if (Multibyte::checkMultibyte($haystack)) {
 637:             $found = false;
 638:             $haystack = Multibyte::strtoupper($haystack);
 639:             $haystack = Multibyte::utf8($haystack);
 640:             $haystackCount = count($haystack);
 641: 
 642:             $matches = array_count_values($haystack);
 643: 
 644:             $needle = Multibyte::strtoupper($needle);
 645:             $needle = Multibyte::utf8($needle);
 646:             $needleCount = count($needle);
 647: 
 648:             $position = $offset;
 649: 
 650:             while (($found === false) && ($position < $haystackCount)) {
 651:                 if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
 652:                     for ($i = 1; $i < $needleCount; $i++) {
 653:                         if ($needle[$i] !== $haystack[$position + $i]) {
 654:                             if ($needle[$i] === $haystack[($position + $i) - 1]) {
 655:                                 $position--;
 656:                                 $found = true;
 657:                                 continue;
 658:                             }
 659:                         }
 660:                     }
 661: 
 662:                     if (!$offset && isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
 663:                         $matches[$needle[0]] = $matches[$needle[0]] - 1;
 664:                     } elseif ($i === $needleCount) {
 665:                         $found = true;
 666:                         $position--;
 667:                     }
 668:                 }
 669:                 $position++;
 670:             }
 671:             return ($found) ? $position : false;
 672:         }
 673:         return strripos($haystack, $needle, $offset);
 674:     }
 675: 
 676: /**
 677:  * Find position of last occurrence of a string in a string.
 678:  *
 679:  * @param string $haystack The string being checked, for the last occurrence of $needle.
 680:  * @param string $needle The string to find in $haystack.
 681:  * @param integer $offset May be specified to begin searching an arbitrary number of characters into the string.
 682:  *    Negative values will stop searching at an arbitrary point prior to the end of the string.
 683:  * @return integer|boolean The numeric position of the last occurrence of $needle in the $haystack string.
 684:  *    If $needle is not found, it returns false.
 685:  */
 686:     public static function strrpos($haystack, $needle, $offset = 0) {
 687:         if (Multibyte::checkMultibyte($haystack)) {
 688:             $found = false;
 689: 
 690:             $haystack = Multibyte::utf8($haystack);
 691:             $haystackCount = count($haystack);
 692: 
 693:             $matches = array_count_values($haystack);
 694: 
 695:             $needle = Multibyte::utf8($needle);
 696:             $needleCount = count($needle);
 697: 
 698:             $position = $offset;
 699: 
 700:             while (($found === false) && ($position < $haystackCount)) {
 701:                 if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
 702:                     for ($i = 1; $i < $needleCount; $i++) {
 703:                         if ($needle[$i] !== $haystack[$position + $i]) {
 704:                             if ($needle[$i] === $haystack[($position + $i) - 1]) {
 705:                                 $position--;
 706:                                 $found = true;
 707:                                 continue;
 708:                             }
 709:                         }
 710:                     }
 711: 
 712:                     if (!$offset && isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
 713:                         $matches[$needle[0]] = $matches[$needle[0]] - 1;
 714:                     } elseif ($i === $needleCount) {
 715:                         $found = true;
 716:                         $position--;
 717:                     }
 718:                 }
 719:                 $position++;
 720:             }
 721:             return ($found) ? $position : false;
 722:         }
 723:         return strrpos($haystack, $needle, $offset);
 724:     }
 725: 
 726: /**
 727:  * Finds first occurrence of a string within another
 728:  *
 729:  * @param string $haystack The string from which to get the first occurrence of $needle.
 730:  * @param string $needle The string to find in $haystack
 731:  * @param boolean $part Determines which portion of $haystack this function returns.
 732:  *    If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
 733:  *    If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
 734:  *    Default value is FALSE.
 735:  * @return string|boolean The portion of $haystack, or true if $needle is not found.
 736:  */
 737:     public static function strstr($haystack, $needle, $part = false) {
 738:         $php = (PHP_VERSION < 5.3);
 739: 
 740:         if (($php && $part) || Multibyte::checkMultibyte($haystack)) {
 741:             $check = Multibyte::utf8($haystack);
 742:             $found = false;
 743: 
 744:             $haystack = Multibyte::utf8($haystack);
 745:             $haystackCount = count($haystack);
 746: 
 747:             $needle = Multibyte::utf8($needle);
 748:             $needleCount = count($needle);
 749: 
 750:             $parts = array();
 751:             $position = 0;
 752: 
 753:             while (($found === false) && ($position < $haystackCount)) {
 754:                 if (isset($needle[0]) && $needle[0] === $check[$position]) {
 755:                     for ($i = 1; $i < $needleCount; $i++) {
 756:                         if ($needle[$i] !== $check[$position + $i]) {
 757:                             break;
 758:                         }
 759:                     }
 760:                     if ($i === $needleCount) {
 761:                         $found = true;
 762:                     }
 763:                 }
 764:                 if (!$found) {
 765:                     $parts[] = $haystack[$position];
 766:                     unset($haystack[$position]);
 767:                 }
 768:                 $position++;
 769:             }
 770: 
 771:             if ($found && $part && !empty($parts)) {
 772:                 return Multibyte::ascii($parts);
 773:             } elseif ($found && !empty($haystack)) {
 774:                 return Multibyte::ascii($haystack);
 775:             }
 776:             return false;
 777:         }
 778: 
 779:         if (!$php) {
 780:             return strstr($haystack, $needle, $part);
 781:         }
 782:         return strstr($haystack, $needle);
 783:     }
 784: 
 785: /**
 786:  * Make a string lowercase
 787:  *
 788:  * @param string $string The string being lowercased.
 789:  * @return string with all alphabetic characters converted to lowercase.
 790:  */
 791:     public static function strtolower($string) {
 792:         $utf8Map = Multibyte::utf8($string);
 793: 
 794:         $length = count($utf8Map);
 795:         $lowerCase = array();
 796: 
 797:         for ($i = 0; $i < $length; $i++) {
 798:             $char = $utf8Map[$i];
 799: 
 800:             if ($char < 128) {
 801:                 $str = strtolower(chr($char));
 802:                 $strlen = strlen($str);
 803:                 for ($ii = 0; $ii < $strlen; $ii++) {
 804:                     $lower = ord(substr($str, $ii, 1));
 805:                 }
 806:                 $lowerCase[] = $lower;
 807:                 $matched = true;
 808:             } else {
 809:                 $matched = false;
 810:                 $keys = self::_find($char, 'upper');
 811: 
 812:                 if (!empty($keys)) {
 813:                     foreach ($keys as $key => $value) {
 814:                         if ($keys[$key]['upper'] == $char && count($keys[$key]['lower'][0]) === 1) {
 815:                             $lowerCase[] = $keys[$key]['lower'][0];
 816:                             $matched = true;
 817:                             break 1;
 818:                         }
 819:                     }
 820:                 }
 821:             }
 822:             if ($matched === false) {
 823:                 $lowerCase[] = $char;
 824:             }
 825:         }
 826:         return Multibyte::ascii($lowerCase);
 827:     }
 828: 
 829: /**
 830:  * Make a string uppercase
 831:  *
 832:  * @param string $string The string being uppercased.
 833:  * @return string with all alphabetic characters converted to uppercase.
 834:  */
 835:     public static function strtoupper($string) {
 836:         $utf8Map = Multibyte::utf8($string);
 837: 
 838:         $length = count($utf8Map);
 839:         $replaced = array();
 840:         $upperCase = array();
 841: 
 842:         for ($i = 0; $i < $length; $i++) {
 843:             $char = $utf8Map[$i];
 844: 
 845:             if ($char < 128) {
 846:                 $str = strtoupper(chr($char));
 847:                 $strlen = strlen($str);
 848:                 for ($ii = 0; $ii < $strlen; $ii++) {
 849:                     $upper = ord(substr($str, $ii, 1));
 850:                 }
 851:                 $upperCase[] = $upper;
 852:                 $matched = true;
 853: 
 854:             } else {
 855:                 $matched = false;
 856:                 $keys = self::_find($char);
 857:                 $keyCount = count($keys);
 858: 
 859:                 if (!empty($keys)) {
 860:                     foreach ($keys as $key => $value) {
 861:                         $matched = false;
 862:                         $replace = 0;
 863:                         if ($length > 1 && count($keys[$key]['lower']) > 1) {
 864:                             $j = 0;
 865: 
 866:                             for ($ii = 0, $count = count($keys[$key]['lower']); $ii < $count; $ii++) {
 867:                                 $nextChar = $utf8Map[$i + $ii];
 868: 
 869:                                 if (isset($nextChar) && ($nextChar == $keys[$key]['lower'][$j + $ii])) {
 870:                                     $replace++;
 871:                                 }
 872:                             }
 873:                             if ($replace == $count) {
 874:                                 $upperCase[] = $keys[$key]['upper'];
 875:                                 $replaced = array_merge($replaced, array_values($keys[$key]['lower']));
 876:                                 $matched = true;
 877:                                 break 1;
 878:                             }
 879:                         } elseif ($length > 1 && $keyCount > 1) {
 880:                             $j = 0;
 881:                             for ($ii = 1; $ii < $keyCount; $ii++) {
 882:                                 $nextChar = $utf8Map[$i + $ii - 1];
 883: 
 884:                                 if (in_array($nextChar, $keys[$ii]['lower'])) {
 885: 
 886:                                     for ($jj = 0, $count = count($keys[$ii]['lower']); $jj < $count; $jj++) {
 887:                                         $nextChar = $utf8Map[$i + $jj];
 888: 
 889:                                         if (isset($nextChar) && ($nextChar == $keys[$ii]['lower'][$j + $jj])) {
 890:                                             $replace++;
 891:                                         }
 892:                                     }
 893:                                     if ($replace == $count) {
 894:                                         $upperCase[] = $keys[$ii]['upper'];
 895:                                         $replaced = array_merge($replaced, array_values($keys[$ii]['lower']));
 896:                                         $matched = true;
 897:                                         break 2;
 898:                                     }
 899:                                 }
 900:                             }
 901:                         }
 902:                         if ($keys[$key]['lower'][0] == $char) {
 903:                             $upperCase[] = $keys[$key]['upper'];
 904:                             $matched = true;
 905:                             break 1;
 906:                         }
 907:                     }
 908:                 }
 909:             }
 910:             if ($matched === false && !in_array($char, $replaced, true)) {
 911:                 $upperCase[] = $char;
 912:             }
 913:         }
 914:         return Multibyte::ascii($upperCase);
 915:     }
 916: 
 917: /**
 918:  * Count the number of substring occurrences
 919:  *
 920:  * @param string $haystack The string being checked.
 921:  * @param string $needle The string being found.
 922:  * @return integer The number of times the $needle substring occurs in the $haystack string.
 923:  */
 924:     public static function substrCount($haystack, $needle) {
 925:         $count = 0;
 926:         $haystack = Multibyte::utf8($haystack);
 927:         $haystackCount = count($haystack);
 928:         $matches = array_count_values($haystack);
 929:         $needle = Multibyte::utf8($needle);
 930:         $needleCount = count($needle);
 931: 
 932:         if ($needleCount === 1 && isset($matches[$needle[0]])) {
 933:             return $matches[$needle[0]];
 934:         }
 935: 
 936:         for ($i = 0; $i < $haystackCount; $i++) {
 937:             if (isset($needle[0]) && $needle[0] === $haystack[$i]) {
 938:                 for ($ii = 1; $ii < $needleCount; $ii++) {
 939:                     if ($needle[$ii] === $haystack[$i + 1]) {
 940:                         if ((isset($needle[$ii + 1]) && $haystack[$i + 2]) && $needle[$ii + 1] !== $haystack[$i + 2]) {
 941:                             $count--;
 942:                         } else {
 943:                             $count++;
 944:                         }
 945:                     }
 946:                 }
 947:             }
 948:         }
 949:         return $count;
 950:     }
 951: 
 952: /**
 953:  * Get part of string
 954:  *
 955:  * @param string $string The string being checked.
 956:  * @param integer $start The first position used in $string.
 957:  * @param integer $length The maximum length of the returned string.
 958:  * @return string The portion of $string specified by the $string and $length parameters.
 959:  */
 960:     public static function substr($string, $start, $length = null) {
 961:         if ($start === 0 && $length === null) {
 962:             return $string;
 963:         }
 964: 
 965:         $string = Multibyte::utf8($string);
 966: 
 967:         for ($i = 1; $i <= $start; $i++) {
 968:             unset($string[$i - 1]);
 969:         }
 970: 
 971:         if ($length === null || count($string) < $length) {
 972:             return Multibyte::ascii($string);
 973:         }
 974:         $string = array_values($string);
 975: 
 976:         $value = array();
 977:         for ($i = 0; $i < $length; $i++) {
 978:             $value[] = $string[$i];
 979:         }
 980:         return Multibyte::ascii($value);
 981:     }
 982: 
 983: /**
 984:  * Prepare a string for mail transport, using the provided encoding
 985:  *
 986:  * @param string $string value to encode
 987:  * @param string $charset charset to use for encoding. defaults to UTF-8
 988:  * @param string $newline
 989:  * @return string
 990:  * @TODO: add support for 'Q'('Quoted Printable') encoding
 991:  */
 992:     public static function mimeEncode($string, $charset = null, $newline = "\r\n") {
 993:         if (!Multibyte::checkMultibyte($string) && strlen($string) < 75) {
 994:             return $string;
 995:         }
 996: 
 997:         if (empty($charset)) {
 998:             $charset = Configure::read('App.encoding');
 999:         }
1000:         $charset = strtoupper($charset);
1001: 
1002:         $start = '=?' . $charset . '?B?';
1003:         $end = '?=';
1004:         $spacer = $end . $newline . ' ' . $start;
1005: 
1006:         $length = 75 - strlen($start) - strlen($end);
1007:         $length = $length - ($length % 4);
1008:         if ($charset == 'UTF-8') {
1009:             $parts = array();
1010:             $maxchars = floor(($length * 3) / 4);
1011:             while (strlen($string) > $maxchars) {
1012:                 $i = (int)$maxchars;
1013:                 $test = ord($string[$i]);
1014:                 while ($test >= 128 && $test <= 191) {
1015:                     $i--;
1016:                     $test = ord($string[$i]);
1017:                 }
1018:                 $parts[] = base64_encode(substr($string, 0, $i));
1019:                 $string = substr($string, $i);
1020:             }
1021:             $parts[] = base64_encode($string);
1022:             $string = implode($spacer, $parts);
1023:         } else {
1024:             $string = chunk_split(base64_encode($string), $length, $spacer);
1025:             $string = preg_replace('/' . preg_quote($spacer) . '$/', '', $string);
1026:         }
1027:         return $start . $string . $end;
1028:     }
1029: 
1030: /**
1031:  * Return the Code points range for Unicode characters
1032:  *
1033:  * @param integer $decimal
1034:  * @return string
1035:  */
1036:     protected static function _codepoint($decimal) {
1037:         if ($decimal > 128 && $decimal < 256) {
1038:             $return = '0080_00ff'; // Latin-1 Supplement
1039:         } elseif ($decimal < 384) {
1040:             $return = '0100_017f'; // Latin Extended-A
1041:         } elseif ($decimal < 592) {
1042:             $return = '0180_024F'; // Latin Extended-B
1043:         } elseif ($decimal < 688) {
1044:             $return = '0250_02af'; // IPA Extensions
1045:         } elseif ($decimal >= 880 && $decimal < 1024) {
1046:             $return = '0370_03ff'; // Greek and Coptic
1047:         } elseif ($decimal < 1280) {
1048:             $return = '0400_04ff'; // Cyrillic
1049:         } elseif ($decimal < 1328) {
1050:             $return = '0500_052f'; // Cyrillic Supplement
1051:         } elseif ($decimal < 1424) {
1052:             $return = '0530_058f'; // Armenian
1053:         } elseif ($decimal >= 7680 && $decimal < 7936) {
1054:             $return = '1e00_1eff'; // Latin Extended Additional
1055:         } elseif ($decimal < 8192) {
1056:             $return = '1f00_1fff'; // Greek Extended
1057:         } elseif ($decimal >= 8448 && $decimal < 8528) {
1058:             $return = '2100_214f'; // Letterlike Symbols
1059:         } elseif ($decimal < 8592) {
1060:             $return = '2150_218f'; // Number Forms
1061:         } elseif ($decimal >= 9312 && $decimal < 9472) {
1062:             $return = '2460_24ff'; // Enclosed Alphanumerics
1063:         } elseif ($decimal >= 11264 && $decimal < 11360) {
1064:             $return = '2c00_2c5f'; // Glagolitic
1065:         } elseif ($decimal < 11392) {
1066:             $return = '2c60_2c7f'; // Latin Extended-C
1067:         } elseif ($decimal < 11520) {
1068:             $return = '2c80_2cff'; // Coptic
1069:         } elseif ($decimal >= 65280 && $decimal < 65520) {
1070:             $return = 'ff00_ffef'; // Halfwidth and Fullwidth Forms
1071:         } else {
1072:             $return = false;
1073:         }
1074:         self::$_codeRange[$decimal] = $return;
1075:         return $return;
1076:     }
1077: 
1078: /**
1079:  * Find the related code folding values for $char
1080:  *
1081:  * @param integer $char decimal value of character
1082:  * @param string $type
1083:  * @return array
1084:  */
1085:     protected static function _find($char, $type = 'lower') {
1086:         $found = array();
1087:         if (!isset(self::$_codeRange[$char])) {
1088:             $range = self::_codepoint($char);
1089:             if ($range === false) {
1090:                 return null;
1091:             }
1092:             if (!Configure::configured('_cake_core_')) {
1093:                 App::uses('PhpReader', 'Configure');
1094:                 Configure::config('_cake_core_', new PhpReader(CAKE . 'Config' . DS));
1095:             }
1096:             Configure::load('unicode' . DS . 'casefolding' . DS . $range, '_cake_core_');
1097:             self::$_caseFold[$range] = Configure::read($range);
1098:             Configure::delete($range);
1099:         }
1100: 
1101:         if (!self::$_codeRange[$char]) {
1102:             return null;
1103:         }
1104:         self::$_table = self::$_codeRange[$char];
1105:         $count = count(self::$_caseFold[self::$_table]);
1106: 
1107:         for ($i = 0; $i < $count; $i++) {
1108:             if ($type === 'lower' && self::$_caseFold[self::$_table][$i][$type][0] === $char) {
1109:                 $found[] = self::$_caseFold[self::$_table][$i];
1110:             } elseif ($type === 'upper' && self::$_caseFold[self::$_table][$i][$type] === $char) {
1111:                 $found[] = self::$_caseFold[self::$_table][$i];
1112:             }
1113:         }
1114:         return $found;
1115:     }
1116: 
1117: /**
1118:  * Check the $string for multibyte characters
1119:  * @param string $string value to test
1120:  * @return boolean
1121:  */
1122:     public static function checkMultibyte($string) {
1123:         $length = strlen($string);
1124: 
1125:         for ($i = 0; $i < $length; $i++ ) {
1126:             $value = ord(($string[$i]));
1127:             if ($value > 128) {
1128:                 return true;
1129:             }
1130:         }
1131:         return false;
1132:     }
1133: 
1134: }
1135: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs