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.8 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.8
      • 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
      • Validator
    • Network
      • Email
      • Http
    • Routing
      • Filter
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper
  • None

Classes

  • I18n
  • L10n
  • Multibyte
  1: <?php
  2: /**
  3:  * Multibyte handling methods.
  4:  *
  5:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7:  *
  8:  * Licensed under The MIT License
  9:  * For full copyright and license information, please see the LICENSE.txt
 10:  * Redistributions of files must retain the above copyright notice.
 11:  *
 12:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 13:  * @link          http://cakephp.org CakePHP(tm) Project
 14:  * @package       Cake.I18n
 15:  * @since         CakePHP(tm) v 1.2.0.6833
 16:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 17:  */
 18: 
 19: /**
 20:  * Multibyte handling methods.
 21:  *
 22:  * @package       Cake.I18n
 23:  */
 24: class Multibyte {
 25: 
 26: /**
 27:  *  Holds the case folding values
 28:  *
 29:  * @var array
 30:  */
 31:     protected static $_caseFold = array();
 32: 
 33: /**
 34:  * Holds an array of Unicode code point ranges
 35:  *
 36:  * @var array
 37:  */
 38:     protected static $_codeRange = array();
 39: 
 40: /**
 41:  * Holds the current code point range
 42:  *
 43:  * @var string
 44:  */
 45:     protected static $_table = null;
 46: 
 47: /**
 48:  * Converts a multibyte character string
 49:  * to the decimal value of the character
 50:  *
 51:  * @param string $string String to convert.
 52:  * @return array
 53:  */
 54:     public static function utf8($string) {
 55:         $map = array();
 56: 
 57:         $values = array();
 58:         $find = 1;
 59:         $length = strlen($string);
 60: 
 61:         for ($i = 0; $i < $length; $i++) {
 62:             $value = ord($string[$i]);
 63: 
 64:             if ($value < 128) {
 65:                 $map[] = $value;
 66:             } else {
 67:                 if (empty($values)) {
 68:                     $find = ($value < 224) ? 2 : 3;
 69:                 }
 70:                 $values[] = $value;
 71: 
 72:                 if (count($values) === $find) {
 73:                     if ($find == 3) {
 74:                         $map[] = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64);
 75:                     } else {
 76:                         $map[] = (($values[0] % 32) * 64) + ($values[1] % 64);
 77:                     }
 78:                     $values = array();
 79:                     $find = 1;
 80:                 }
 81:             }
 82:         }
 83:         return $map;
 84:     }
 85: 
 86: /**
 87:  * Converts the decimal value of a multibyte character string
 88:  * to a string
 89:  *
 90:  * @param array $array Values array.
 91:  * @return string
 92:  */
 93:     public static function ascii($array) {
 94:         $ascii = '';
 95: 
 96:         foreach ($array as $utf8) {
 97:             if ($utf8 < 128) {
 98:                 $ascii .= chr($utf8);
 99:             } elseif ($utf8 < 2048) {
100:                 $ascii .= chr(192 + (($utf8 - ($utf8 % 64)) / 64));
101:                 $ascii .= chr(128 + ($utf8 % 64));
102:             } else {
103:                 $ascii .= chr(224 + (($utf8 - ($utf8 % 4096)) / 4096));
104:                 $ascii .= chr(128 + ((($utf8 % 4096) - ($utf8 % 64)) / 64));
105:                 $ascii .= chr(128 + ($utf8 % 64));
106:             }
107:         }
108:         return $ascii;
109:     }
110: 
111: /**
112:  * Find position of first occurrence of a case-insensitive string.
113:  *
114:  * @param string $haystack The string from which to get the position of the first occurrence of $needle.
115:  * @param string $needle The string to find in $haystack.
116:  * @param int $offset The position in $haystack to start searching.
117:  * @return int|bool The numeric position of the first occurrence of $needle in the $haystack string,
118:  *    or false if $needle is not found.
119:  */
120:     public static function stripos($haystack, $needle, $offset = 0) {
121:         if (Multibyte::checkMultibyte($haystack)) {
122:             $haystack = Multibyte::strtoupper($haystack);
123:             $needle = Multibyte::strtoupper($needle);
124:             return Multibyte::strpos($haystack, $needle, $offset);
125:         }
126:         return stripos($haystack, $needle, $offset);
127:     }
128: 
129: /**
130:  * Finds first occurrence of a string within another, case insensitive.
131:  *
132:  * @param string $haystack The string from which to get the first occurrence of $needle.
133:  * @param string $needle The string to find in $haystack.
134:  * @param bool $part Determines which portion of $haystack this function returns.
135:  *    If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
136:  *    If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
137:  *    Default value is false.
138:  * @return int|bool The portion of $haystack, or false if $needle is not found.
139:  */
140:     public static function stristr($haystack, $needle, $part = false) {
141:         $php = (PHP_VERSION < 5.3);
142: 
143:         if (($php && $part) || Multibyte::checkMultibyte($haystack)) {
144:             $check = Multibyte::strtoupper($haystack);
145:             $check = Multibyte::utf8($check);
146:             $found = false;
147: 
148:             $haystack = Multibyte::utf8($haystack);
149:             $haystackCount = count($haystack);
150: 
151:             $needle = Multibyte::strtoupper($needle);
152:             $needle = Multibyte::utf8($needle);
153:             $needleCount = count($needle);
154: 
155:             $parts = array();
156:             $position = 0;
157: 
158:             while (($found === false) && ($position < $haystackCount)) {
159:                 if (isset($needle[0]) && $needle[0] === $check[$position]) {
160:                     for ($i = 1; $i < $needleCount; $i++) {
161:                         if ($needle[$i] !== $check[$position + $i]) {
162:                             break;
163:                         }
164:                     }
165:                     if ($i === $needleCount) {
166:                         $found = true;
167:                     }
168:                 }
169:                 if (!$found) {
170:                     $parts[] = $haystack[$position];
171:                     unset($haystack[$position]);
172:                 }
173:                 $position++;
174:             }
175: 
176:             if ($found && $part && !empty($parts)) {
177:                 return Multibyte::ascii($parts);
178:             } elseif ($found && !empty($haystack)) {
179:                 return Multibyte::ascii($haystack);
180:             }
181:             return false;
182:         }
183: 
184:         if (!$php) {
185:             return stristr($haystack, $needle, $part);
186:         }
187:         return stristr($haystack, $needle);
188:     }
189: 
190: /**
191:  * Get string length.
192:  *
193:  * @param string $string The string being checked for length.
194:  * @return int The number of characters in string $string
195:  */
196:     public static function strlen($string) {
197:         if (Multibyte::checkMultibyte($string)) {
198:             $string = Multibyte::utf8($string);
199:             return count($string);
200:         }
201:         return strlen($string);
202:     }
203: 
204: /**
205:  * Find position of first occurrence of a string.
206:  *
207:  * @param string $haystack The string being checked.
208:  * @param string $needle The position counted from the beginning of haystack.
209:  * @param int $offset The search offset. If it is not specified, 0 is used.
210:  * @return int|bool The numeric position of the first occurrence of $needle in the $haystack string.
211:  *    If $needle is not found, it returns false.
212:  */
213:     public static function strpos($haystack, $needle, $offset = 0) {
214:         if (Multibyte::checkMultibyte($haystack)) {
215:             $found = false;
216: 
217:             $haystack = Multibyte::utf8($haystack);
218:             $haystackCount = count($haystack);
219: 
220:             $needle = Multibyte::utf8($needle);
221:             $needleCount = count($needle);
222: 
223:             $position = $offset;
224: 
225:             while (($found === false) && ($position < $haystackCount)) {
226:                 if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
227:                     for ($i = 1; $i < $needleCount; $i++) {
228:                         if ($needle[$i] !== $haystack[$position + $i]) {
229:                             break;
230:                         }
231:                     }
232:                     if ($i === $needleCount) {
233:                         $found = true;
234:                         $position--;
235:                     }
236:                 }
237:                 $position++;
238:             }
239:             if ($found) {
240:                 return $position;
241:             }
242:             return false;
243:         }
244:         return strpos($haystack, $needle, $offset);
245:     }
246: 
247: /**
248:  * Finds the last occurrence of a character in a string within another.
249:  *
250:  * @param string $haystack The string from which to get the last occurrence of $needle.
251:  * @param string $needle The string to find in $haystack.
252:  * @param bool $part Determines which portion of $haystack this function returns.
253:  *    If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
254:  *    If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
255:  *    Default value is false.
256:  * @return string|bool The portion of $haystack. or false if $needle is not found.
257:  */
258:     public static function strrchr($haystack, $needle, $part = false) {
259:         $check = Multibyte::utf8($haystack);
260:         $found = false;
261: 
262:         $haystack = Multibyte::utf8($haystack);
263:         $haystackCount = count($haystack);
264: 
265:         $matches = array_count_values($check);
266: 
267:         $needle = Multibyte::utf8($needle);
268:         $needleCount = count($needle);
269: 
270:         $parts = array();
271:         $position = 0;
272: 
273:         while (($found === false) && ($position < $haystackCount)) {
274:             if (isset($needle[0]) && $needle[0] === $check[$position]) {
275:                 for ($i = 1; $i < $needleCount; $i++) {
276:                     if ($needle[$i] !== $check[$position + $i]) {
277:                         if ($needle[$i] === $check[($position + $i) - 1]) {
278:                             $found = true;
279:                         }
280:                         unset($parts[$position - 1]);
281:                         $haystack = array_merge(array($haystack[$position]), $haystack);
282:                         break;
283:                     }
284:                 }
285:                 if (isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
286:                     $matches[$needle[0]] = $matches[$needle[0]] - 1;
287:                 } elseif ($i === $needleCount) {
288:                     $found = true;
289:                 }
290:             }
291: 
292:             if (!$found && isset($haystack[$position])) {
293:                 $parts[] = $haystack[$position];
294:                 unset($haystack[$position]);
295:             }
296:             $position++;
297:         }
298: 
299:         if ($found && $part && !empty($parts)) {
300:             return Multibyte::ascii($parts);
301:         } elseif ($found && !empty($haystack)) {
302:             return Multibyte::ascii($haystack);
303:         }
304:         return false;
305:     }
306: 
307: /**
308:  * Finds the last occurrence of a character in a string within another, case insensitive.
309:  *
310:  * @param string $haystack The string from which to get the last occurrence of $needle.
311:  * @param string $needle The string to find in $haystack.
312:  * @param bool $part Determines which portion of $haystack this function returns.
313:  *    If set to true, it returns all of $haystack from the beginning to the last occurrence of $needle.
314:  *    If set to false, it returns all of $haystack from the last occurrence of $needle to the end,
315:  *    Default value is false.
316:  * @return string|bool The portion of $haystack. or false if $needle is not found.
317:  */
318:     public static function strrichr($haystack, $needle, $part = false) {
319:         $check = Multibyte::strtoupper($haystack);
320:         $check = Multibyte::utf8($check);
321:         $found = false;
322: 
323:         $haystack = Multibyte::utf8($haystack);
324:         $haystackCount = count($haystack);
325: 
326:         $matches = array_count_values($check);
327: 
328:         $needle = Multibyte::strtoupper($needle);
329:         $needle = Multibyte::utf8($needle);
330:         $needleCount = count($needle);
331: 
332:         $parts = array();
333:         $position = 0;
334: 
335:         while (($found === false) && ($position < $haystackCount)) {
336:             if (isset($needle[0]) && $needle[0] === $check[$position]) {
337:                 for ($i = 1; $i < $needleCount; $i++) {
338:                     if ($needle[$i] !== $check[$position + $i]) {
339:                         if ($needle[$i] === $check[($position + $i) - 1]) {
340:                             $found = true;
341:                         }
342:                         unset($parts[$position - 1]);
343:                         $haystack = array_merge(array($haystack[$position]), $haystack);
344:                         break;
345:                     }
346:                 }
347:                 if (isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
348:                     $matches[$needle[0]] = $matches[$needle[0]] - 1;
349:                 } elseif ($i === $needleCount) {
350:                     $found = true;
351:                 }
352:             }
353: 
354:             if (!$found && isset($haystack[$position])) {
355:                 $parts[] = $haystack[$position];
356:                 unset($haystack[$position]);
357:             }
358:             $position++;
359:         }
360: 
361:         if ($found && $part && !empty($parts)) {
362:             return Multibyte::ascii($parts);
363:         } elseif ($found && !empty($haystack)) {
364:             return Multibyte::ascii($haystack);
365:         }
366:         return false;
367:     }
368: 
369: /**
370:  * Finds position of last occurrence of a string within another, case insensitive
371:  *
372:  * @param string $haystack The string from which to get the position of the last occurrence of $needle.
373:  * @param string $needle The string to find in $haystack.
374:  * @param int $offset The position in $haystack to start searching.
375:  * @return int|bool The numeric position of the last occurrence of $needle in the $haystack string,
376:  *    or false if $needle is not found.
377:  */
378:     public static function strripos($haystack, $needle, $offset = 0) {
379:         if (Multibyte::checkMultibyte($haystack)) {
380:             $found = false;
381:             $haystack = Multibyte::strtoupper($haystack);
382:             $haystack = Multibyte::utf8($haystack);
383:             $haystackCount = count($haystack);
384: 
385:             $matches = array_count_values($haystack);
386: 
387:             $needle = Multibyte::strtoupper($needle);
388:             $needle = Multibyte::utf8($needle);
389:             $needleCount = count($needle);
390: 
391:             $position = $offset;
392: 
393:             while (($found === false) && ($position < $haystackCount)) {
394:                 if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
395:                     for ($i = 1; $i < $needleCount; $i++) {
396:                         if ($needle[$i] !== $haystack[$position + $i]) {
397:                             if ($needle[$i] === $haystack[($position + $i) - 1]) {
398:                                 $position--;
399:                                 $found = true;
400:                                 continue;
401:                             }
402:                         }
403:                     }
404: 
405:                     if (!$offset && isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
406:                         $matches[$needle[0]] = $matches[$needle[0]] - 1;
407:                     } elseif ($i === $needleCount) {
408:                         $found = true;
409:                         $position--;
410:                     }
411:                 }
412:                 $position++;
413:             }
414:             return ($found) ? $position : false;
415:         }
416:         return strripos($haystack, $needle, $offset);
417:     }
418: 
419: /**
420:  * Find position of last occurrence of a string in a string.
421:  *
422:  * @param string $haystack The string being checked, for the last occurrence of $needle.
423:  * @param string $needle The string to find in $haystack.
424:  * @param int $offset May be specified to begin searching an arbitrary number of characters into the string.
425:  *    Negative values will stop searching at an arbitrary point prior to the end of the string.
426:  * @return int|bool The numeric position of the last occurrence of $needle in the $haystack string.
427:  *    If $needle is not found, it returns false.
428:  */
429:     public static function strrpos($haystack, $needle, $offset = 0) {
430:         if (Multibyte::checkMultibyte($haystack)) {
431:             $found = false;
432: 
433:             $haystack = Multibyte::utf8($haystack);
434:             $haystackCount = count($haystack);
435: 
436:             $matches = array_count_values($haystack);
437: 
438:             $needle = Multibyte::utf8($needle);
439:             $needleCount = count($needle);
440: 
441:             $position = $offset;
442: 
443:             while (($found === false) && ($position < $haystackCount)) {
444:                 if (isset($needle[0]) && $needle[0] === $haystack[$position]) {
445:                     for ($i = 1; $i < $needleCount; $i++) {
446:                         if ($needle[$i] !== $haystack[$position + $i]) {
447:                             if ($needle[$i] === $haystack[($position + $i) - 1]) {
448:                                 $position--;
449:                                 $found = true;
450:                                 continue;
451:                             }
452:                         }
453:                     }
454: 
455:                     if (!$offset && isset($matches[$needle[0]]) && $matches[$needle[0]] > 1) {
456:                         $matches[$needle[0]] = $matches[$needle[0]] - 1;
457:                     } elseif ($i === $needleCount) {
458:                         $found = true;
459:                         $position--;
460:                     }
461:                 }
462:                 $position++;
463:             }
464:             return ($found) ? $position : false;
465:         }
466:         return strrpos($haystack, $needle, $offset);
467:     }
468: 
469: /**
470:  * Finds first occurrence of a string within another
471:  *
472:  * @param string $haystack The string from which to get the first occurrence of $needle.
473:  * @param string $needle The string to find in $haystack
474:  * @param bool $part Determines which portion of $haystack this function returns.
475:  *    If set to true, it returns all of $haystack from the beginning to the first occurrence of $needle.
476:  *    If set to false, it returns all of $haystack from the first occurrence of $needle to the end,
477:  *    Default value is FALSE.
478:  * @return string|bool The portion of $haystack, or true if $needle is not found.
479:  */
480:     public static function strstr($haystack, $needle, $part = false) {
481:         $php = (PHP_VERSION < 5.3);
482: 
483:         if (($php && $part) || Multibyte::checkMultibyte($haystack)) {
484:             $check = Multibyte::utf8($haystack);
485:             $found = false;
486: 
487:             $haystack = Multibyte::utf8($haystack);
488:             $haystackCount = count($haystack);
489: 
490:             $needle = Multibyte::utf8($needle);
491:             $needleCount = count($needle);
492: 
493:             $parts = array();
494:             $position = 0;
495: 
496:             while (($found === false) && ($position < $haystackCount)) {
497:                 if (isset($needle[0]) && $needle[0] === $check[$position]) {
498:                     for ($i = 1; $i < $needleCount; $i++) {
499:                         if ($needle[$i] !== $check[$position + $i]) {
500:                             break;
501:                         }
502:                     }
503:                     if ($i === $needleCount) {
504:                         $found = true;
505:                     }
506:                 }
507:                 if (!$found) {
508:                     $parts[] = $haystack[$position];
509:                     unset($haystack[$position]);
510:                 }
511:                 $position++;
512:             }
513: 
514:             if ($found && $part && !empty($parts)) {
515:                 return Multibyte::ascii($parts);
516:             } elseif ($found && !empty($haystack)) {
517:                 return Multibyte::ascii($haystack);
518:             }
519:             return false;
520:         }
521: 
522:         if (!$php) {
523:             return strstr($haystack, $needle, $part);
524:         }
525:         return strstr($haystack, $needle);
526:     }
527: 
528: /**
529:  * Make a string lowercase
530:  *
531:  * @param string $string The string being lowercased.
532:  * @return string with all alphabetic characters converted to lowercase.
533:  */
534:     public static function strtolower($string) {
535:         $utf8Map = Multibyte::utf8($string);
536: 
537:         $length = count($utf8Map);
538:         $lowerCase = array();
539: 
540:         for ($i = 0; $i < $length; $i++) {
541:             $char = $utf8Map[$i];
542: 
543:             if ($char < 128) {
544:                 $str = strtolower(chr($char));
545:                 $strlen = strlen($str);
546:                 for ($ii = 0; $ii < $strlen; $ii++) {
547:                     $lower = ord(substr($str, $ii, 1));
548:                 }
549:                 $lowerCase[] = $lower;
550:                 $matched = true;
551:             } else {
552:                 $matched = false;
553:                 $keys = static::_find($char, 'upper');
554: 
555:                 if (!empty($keys)) {
556:                     foreach ($keys as $key => $value) {
557:                         if ($keys[$key]['upper'] == $char && count($keys[$key]['lower'][0]) === 1) {
558:                             $lowerCase[] = $keys[$key]['lower'][0];
559:                             $matched = true;
560:                             break 1;
561:                         }
562:                     }
563:                 }
564:             }
565:             if ($matched === false) {
566:                 $lowerCase[] = $char;
567:             }
568:         }
569:         return Multibyte::ascii($lowerCase);
570:     }
571: 
572: /**
573:  * Make a string uppercase
574:  *
575:  * @param string $string The string being uppercased.
576:  * @return string with all alphabetic characters converted to uppercase.
577:  */
578:     public static function strtoupper($string) {
579:         $utf8Map = Multibyte::utf8($string);
580: 
581:         $length = count($utf8Map);
582:         $replaced = array();
583:         $upperCase = array();
584: 
585:         for ($i = 0; $i < $length; $i++) {
586:             $char = $utf8Map[$i];
587: 
588:             if ($char < 128) {
589:                 $str = strtoupper(chr($char));
590:                 $strlen = strlen($str);
591:                 for ($ii = 0; $ii < $strlen; $ii++) {
592:                     $upper = ord(substr($str, $ii, 1));
593:                 }
594:                 $upperCase[] = $upper;
595:                 $matched = true;
596: 
597:             } else {
598:                 $matched = false;
599:                 $keys = static::_find($char);
600:                 $keyCount = count($keys);
601: 
602:                 if (!empty($keys)) {
603:                     foreach ($keys as $key => $value) {
604:                         $matched = false;
605:                         $replace = 0;
606:                         if ($length > 1 && count($keys[$key]['lower']) > 1) {
607:                             $j = 0;
608: 
609:                             for ($ii = 0, $count = count($keys[$key]['lower']); $ii < $count; $ii++) {
610:                                 $nextChar = $utf8Map[$i + $ii];
611: 
612:                                 if (isset($nextChar) && ($nextChar == $keys[$key]['lower'][$j + $ii])) {
613:                                     $replace++;
614:                                 }
615:                             }
616:                             if ($replace == $count) {
617:                                 $upperCase[] = $keys[$key]['upper'];
618:                                 $replaced = array_merge($replaced, array_values($keys[$key]['lower']));
619:                                 $matched = true;
620:                                 break 1;
621:                             }
622:                         } elseif ($length > 1 && $keyCount > 1) {
623:                             $j = 0;
624:                             for ($ii = 1; $ii < $keyCount; $ii++) {
625:                                 $nextChar = $utf8Map[$i + $ii - 1];
626: 
627:                                 if (in_array($nextChar, $keys[$ii]['lower'])) {
628: 
629:                                     for ($jj = 0, $count = count($keys[$ii]['lower']); $jj < $count; $jj++) {
630:                                         $nextChar = $utf8Map[$i + $jj];
631: 
632:                                         if (isset($nextChar) && ($nextChar == $keys[$ii]['lower'][$j + $jj])) {
633:                                             $replace++;
634:                                         }
635:                                     }
636:                                     if ($replace == $count) {
637:                                         $upperCase[] = $keys[$ii]['upper'];
638:                                         $replaced = array_merge($replaced, array_values($keys[$ii]['lower']));
639:                                         $matched = true;
640:                                         break 2;
641:                                     }
642:                                 }
643:                             }
644:                         }
645:                         if ($keys[$key]['lower'][0] == $char) {
646:                             $upperCase[] = $keys[$key]['upper'];
647:                             $matched = true;
648:                             break 1;
649:                         }
650:                     }
651:                 }
652:             }
653:             if ($matched === false && !in_array($char, $replaced, true)) {
654:                 $upperCase[] = $char;
655:             }
656:         }
657:         return Multibyte::ascii($upperCase);
658:     }
659: 
660: /**
661:  * Count the number of substring occurrences
662:  *
663:  * @param string $haystack The string being checked.
664:  * @param string $needle The string being found.
665:  * @return int The number of times the $needle substring occurs in the $haystack string.
666:  */
667:     public static function substrCount($haystack, $needle) {
668:         $count = 0;
669:         $haystack = Multibyte::utf8($haystack);
670:         $haystackCount = count($haystack);
671:         $matches = array_count_values($haystack);
672:         $needle = Multibyte::utf8($needle);
673:         $needleCount = count($needle);
674: 
675:         if ($needleCount === 1 && isset($matches[$needle[0]])) {
676:             return $matches[$needle[0]];
677:         }
678: 
679:         for ($i = 0; $i < $haystackCount; $i++) {
680:             if (isset($needle[0]) && $needle[0] === $haystack[$i]) {
681:                 for ($ii = 1; $ii < $needleCount; $ii++) {
682:                     if ($needle[$ii] === $haystack[$i + 1]) {
683:                         if ((isset($needle[$ii + 1]) && $haystack[$i + 2]) && $needle[$ii + 1] !== $haystack[$i + 2]) {
684:                             $count--;
685:                         } else {
686:                             $count++;
687:                         }
688:                     }
689:                 }
690:             }
691:         }
692:         return $count;
693:     }
694: 
695: /**
696:  * Get part of string
697:  *
698:  * @param string $string The string being checked.
699:  * @param int $start The first position used in $string.
700:  * @param int $length The maximum length of the returned string.
701:  * @return string The portion of $string specified by the $string and $length parameters.
702:  */
703:     public static function substr($string, $start, $length = null) {
704:         if ($start === 0 && $length === null) {
705:             return $string;
706:         }
707: 
708:         $string = Multibyte::utf8($string);
709: 
710:         for ($i = 1; $i <= $start; $i++) {
711:             unset($string[$i - 1]);
712:         }
713: 
714:         if ($length === null || count($string) < $length) {
715:             return Multibyte::ascii($string);
716:         }
717:         $string = array_values($string);
718: 
719:         $value = array();
720:         for ($i = 0; $i < $length; $i++) {
721:             $value[] = $string[$i];
722:         }
723:         return Multibyte::ascii($value);
724:     }
725: 
726: /**
727:  * Prepare a string for mail transport, using the provided encoding
728:  *
729:  * @param string $string value to encode
730:  * @param string $charset charset to use for encoding. defaults to UTF-8
731:  * @param string $newline Newline string.
732:  * @return string
733:  */
734:     public static function mimeEncode($string, $charset = null, $newline = "\r\n") {
735:         if (!Multibyte::checkMultibyte($string) && strlen($string) < 75) {
736:             return $string;
737:         }
738: 
739:         if (empty($charset)) {
740:             $charset = Configure::read('App.encoding');
741:         }
742:         $charset = strtoupper($charset);
743: 
744:         $start = '=?' . $charset . '?B?';
745:         $end = '?=';
746:         $spacer = $end . $newline . ' ' . $start;
747: 
748:         $length = 75 - strlen($start) - strlen($end);
749:         $length = $length - ($length % 4);
750:         if ($charset === 'UTF-8') {
751:             $parts = array();
752:             $maxchars = floor(($length * 3) / 4);
753:             $stringLength = strlen($string);
754:             while ($stringLength > $maxchars) {
755:                 $i = (int)$maxchars;
756:                 $test = ord($string[$i]);
757:                 while ($test >= 128 && $test <= 191) {
758:                     $i--;
759:                     $test = ord($string[$i]);
760:                 }
761:                 $parts[] = base64_encode(substr($string, 0, $i));
762:                 $string = substr($string, $i);
763:                 $stringLength = strlen($string);
764:             }
765:             $parts[] = base64_encode($string);
766:             $string = implode($spacer, $parts);
767:         } else {
768:             $string = chunk_split(base64_encode($string), $length, $spacer);
769:             $string = preg_replace('/' . preg_quote($spacer) . '$/', '', $string);
770:         }
771:         return $start . $string . $end;
772:     }
773: 
774: /**
775:  * Return the Code points range for Unicode characters
776:  *
777:  * @param int $decimal Decimal value.
778:  * @return string
779:  */
780:     protected static function _codepoint($decimal) {
781:         if ($decimal > 128 && $decimal < 256) {
782:             $return = '0080_00ff'; // Latin-1 Supplement
783:         } elseif ($decimal < 384) {
784:             $return = '0100_017f'; // Latin Extended-A
785:         } elseif ($decimal < 592) {
786:             $return = '0180_024F'; // Latin Extended-B
787:         } elseif ($decimal < 688) {
788:             $return = '0250_02af'; // IPA Extensions
789:         } elseif ($decimal >= 880 && $decimal < 1024) {
790:             $return = '0370_03ff'; // Greek and Coptic
791:         } elseif ($decimal < 1280) {
792:             $return = '0400_04ff'; // Cyrillic
793:         } elseif ($decimal < 1328) {
794:             $return = '0500_052f'; // Cyrillic Supplement
795:         } elseif ($decimal < 1424) {
796:             $return = '0530_058f'; // Armenian
797:         } elseif ($decimal >= 7680 && $decimal < 7936) {
798:             $return = '1e00_1eff'; // Latin Extended Additional
799:         } elseif ($decimal < 8192) {
800:             $return = '1f00_1fff'; // Greek Extended
801:         } elseif ($decimal >= 8448 && $decimal < 8528) {
802:             $return = '2100_214f'; // Letterlike Symbols
803:         } elseif ($decimal < 8592) {
804:             $return = '2150_218f'; // Number Forms
805:         } elseif ($decimal >= 9312 && $decimal < 9472) {
806:             $return = '2460_24ff'; // Enclosed Alphanumerics
807:         } elseif ($decimal >= 11264 && $decimal < 11360) {
808:             $return = '2c00_2c5f'; // Glagolitic
809:         } elseif ($decimal < 11392) {
810:             $return = '2c60_2c7f'; // Latin Extended-C
811:         } elseif ($decimal < 11520) {
812:             $return = '2c80_2cff'; // Coptic
813:         } elseif ($decimal >= 65280 && $decimal < 65520) {
814:             $return = 'ff00_ffef'; // Halfwidth and Fullwidth Forms
815:         } else {
816:             $return = false;
817:         }
818:         static::$_codeRange[$decimal] = $return;
819:         return $return;
820:     }
821: 
822: /**
823:  * Find the related code folding values for $char
824:  *
825:  * @param int $char decimal value of character
826:  * @param string $type Type 'lower' or 'upper'. Defaults to 'lower'.
827:  * @return array
828:  */
829:     protected static function _find($char, $type = 'lower') {
830:         $found = array();
831:         if (!isset(static::$_codeRange[$char])) {
832:             $range = static::_codepoint($char);
833:             if ($range === false) {
834:                 return array();
835:             }
836:             if (!Configure::configured('_cake_core_')) {
837:                 App::uses('PhpReader', 'Configure');
838:                 Configure::config('_cake_core_', new PhpReader(CAKE . 'Config' . DS));
839:             }
840:             Configure::load('unicode' . DS . 'casefolding' . DS . $range, '_cake_core_');
841:             static::$_caseFold[$range] = Configure::read($range);
842:             Configure::delete($range);
843:         }
844: 
845:         if (!static::$_codeRange[$char]) {
846:             return array();
847:         }
848:         static::$_table = static::$_codeRange[$char];
849:         $count = count(static::$_caseFold[static::$_table]);
850: 
851:         for ($i = 0; $i < $count; $i++) {
852:             if ($type === 'lower' && static::$_caseFold[static::$_table][$i][$type][0] === $char) {
853:                 $found[] = static::$_caseFold[static::$_table][$i];
854:             } elseif ($type === 'upper' && static::$_caseFold[static::$_table][$i][$type] === $char) {
855:                 $found[] = static::$_caseFold[static::$_table][$i];
856:             }
857:         }
858:         return $found;
859:     }
860: 
861: /**
862:  * Check the $string for multibyte characters
863:  *
864:  * @param string $string Value to test.
865:  * @return bool
866:  */
867:     public static function checkMultibyte($string) {
868:         $length = strlen($string);
869: 
870:         for ($i = 0; $i < $length; $i++) {
871:             $value = ord(($string[$i]));
872:             if ($value > 128) {
873:                 return true;
874:             }
875:         }
876:         return false;
877:     }
878: 
879: }
880: 
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