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

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.2
      • 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

Classes

  • CakeNumber
  • CakeTime
  • ClassRegistry
  • Debugger
  • File
  • Folder
  • Hash
  • Inflector
  • ObjectCollection
  • Sanitize
  • Security
  • Set
  • String
  • Validation
  • Xml
  1: <?php
  2: /**
  3:  * String handling methods.
  4:  *
  5:  * PHP 5
  6:  *
  7:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8:  * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9:  *
 10:  * Licensed under The MIT License
 11:  * Redistributions of files must retain the above copyright notice.
 12:  *
 13:  * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 14:  * @link          http://cakephp.org CakePHP(tm) Project
 15:  * @package       Cake.Utility
 16:  * @since         CakePHP(tm) v 1.2.0.5551
 17:  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 18:  */
 19: 
 20: /**
 21:  * String handling methods.
 22:  *
 23:  *
 24:  * @package       Cake.Utility
 25:  */
 26: class String {
 27: 
 28: /**
 29:  * Generate a random UUID
 30:  *
 31:  * @see http://www.ietf.org/rfc/rfc4122.txt
 32:  * @return RFC 4122 UUID
 33:  */
 34:     public static function uuid() {
 35:         $node = env('SERVER_ADDR');
 36: 
 37:         if (strpos($node, ':') !== false) {
 38:             if (substr_count($node, '::')) {
 39:                 $node = str_replace(
 40:                     '::', str_repeat(':0000', 8 - substr_count($node, ':')) . ':', $node
 41:                 );
 42:             }
 43:             $node = explode(':', $node);
 44:             $ipSix = '';
 45: 
 46:             foreach ($node as $id) {
 47:                 $ipSix .= str_pad(base_convert($id, 16, 2), 16, 0, STR_PAD_LEFT);
 48:             }
 49:             $node = base_convert($ipSix, 2, 10);
 50: 
 51:             if (strlen($node) < 38) {
 52:                 $node = null;
 53:             } else {
 54:                 $node = crc32($node);
 55:             }
 56:         } elseif (empty($node)) {
 57:             $host = env('HOSTNAME');
 58: 
 59:             if (empty($host)) {
 60:                 $host = env('HOST');
 61:             }
 62: 
 63:             if (!empty($host)) {
 64:                 $ip = gethostbyname($host);
 65: 
 66:                 if ($ip === $host) {
 67:                     $node = crc32($host);
 68:                 } else {
 69:                     $node = ip2long($ip);
 70:                 }
 71:             }
 72:         } elseif ($node !== '127.0.0.1') {
 73:             $node = ip2long($node);
 74:         } else {
 75:             $node = null;
 76:         }
 77: 
 78:         if (empty($node)) {
 79:             $node = crc32(Configure::read('Security.salt'));
 80:         }
 81: 
 82:         if (function_exists('hphp_get_thread_id')) {
 83:             $pid = hphp_get_thread_id();
 84:         } elseif (function_exists('zend_thread_id')) {
 85:             $pid = zend_thread_id();
 86:         } else {
 87:             $pid = getmypid();
 88:         }
 89: 
 90:         if (!$pid || $pid > 65535) {
 91:             $pid = mt_rand(0, 0xfff) | 0x4000;
 92:         }
 93: 
 94:         list($timeMid, $timeLow) = explode(' ', microtime());
 95:         $uuid = sprintf(
 96:             "%08x-%04x-%04x-%02x%02x-%04x%08x", (int)$timeLow, (int)substr($timeMid, 2) & 0xffff,
 97:             mt_rand(0, 0xfff) | 0x4000, mt_rand(0, 0x3f) | 0x80, mt_rand(0, 0xff), $pid, $node
 98:         );
 99: 
100:         return $uuid;
101:     }
102: 
103: /**
104:  * Tokenizes a string using $separator, ignoring any instance of $separator that appears between
105:  * $leftBound and $rightBound
106:  *
107:  * @param string $data The data to tokenize
108:  * @param string $separator The token to split the data on.
109:  * @param string $leftBound The left boundary to ignore separators in.
110:  * @param string $rightBound The right boundary to ignore separators in.
111:  * @return array Array of tokens in $data.
112:  */
113:     public static function tokenize($data, $separator = ',', $leftBound = '(', $rightBound = ')') {
114:         if (empty($data) || is_array($data)) {
115:             return $data;
116:         }
117: 
118:         $depth = 0;
119:         $offset = 0;
120:         $buffer = '';
121:         $results = array();
122:         $length = strlen($data);
123:         $open = false;
124: 
125:         while ($offset <= $length) {
126:             $tmpOffset = -1;
127:             $offsets = array(
128:                 strpos($data, $separator, $offset),
129:                 strpos($data, $leftBound, $offset),
130:                 strpos($data, $rightBound, $offset)
131:             );
132:             for ($i = 0; $i < 3; $i++) {
133:                 if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset == -1)) {
134:                     $tmpOffset = $offsets[$i];
135:                 }
136:             }
137:             if ($tmpOffset !== -1) {
138:                 $buffer .= substr($data, $offset, ($tmpOffset - $offset));
139:                 if ($data{$tmpOffset} == $separator && $depth == 0) {
140:                     $results[] = $buffer;
141:                     $buffer = '';
142:                 } else {
143:                     $buffer .= $data{$tmpOffset};
144:                 }
145:                 if ($leftBound != $rightBound) {
146:                     if ($data{$tmpOffset} == $leftBound) {
147:                         $depth++;
148:                     }
149:                     if ($data{$tmpOffset} == $rightBound) {
150:                         $depth--;
151:                     }
152:                 } else {
153:                     if ($data{$tmpOffset} == $leftBound) {
154:                         if (!$open) {
155:                             $depth++;
156:                             $open = true;
157:                         } else {
158:                             $depth--;
159:                             $open = false;
160:                         }
161:                     }
162:                 }
163:                 $offset = ++$tmpOffset;
164:             } else {
165:                 $results[] = $buffer . substr($data, $offset);
166:                 $offset = $length + 1;
167:             }
168:         }
169:         if (empty($results) && !empty($buffer)) {
170:             $results[] = $buffer;
171:         }
172: 
173:         if (!empty($results)) {
174:             $data = array_map('trim', $results);
175:         } else {
176:             $data = array();
177:         }
178:         return $data;
179:     }
180: 
181: /**
182:  * Replaces variable placeholders inside a $str with any given $data. Each key in the $data array
183:  * corresponds to a variable placeholder name in $str.
184:  * Example: `String::insert(':name is :age years old.', array('name' => 'Bob', '65'));`
185:  * Returns: Bob is 65 years old.
186:  *
187:  * Available $options are:
188:  *
189:  * - before: The character or string in front of the name of the variable placeholder (Defaults to `:`)
190:  * - after: The character or string after the name of the variable placeholder (Defaults to null)
191:  * - escape: The character or string used to escape the before character / string (Defaults to `\`)
192:  * - format: A regex to use for matching variable placeholders. Default is: `/(?<!\\)\:%s/`
193:  *   (Overwrites before, after, breaks escape / clean)
194:  * - clean: A boolean or array with instructions for String::cleanInsert
195:  *
196:  * @param string $str A string containing variable placeholders
197:  * @param string $data A key => val array where each key stands for a placeholder variable name
198:  *     to be replaced with val
199:  * @param string $options An array of options, see description above
200:  * @return string
201:  */
202:     public static function insert($str, $data, $options = array()) {
203:         $defaults = array(
204:             'before' => ':', 'after' => null, 'escape' => '\\', 'format' => null, 'clean' => false
205:         );
206:         $options += $defaults;
207:         $format = $options['format'];
208:         $data = (array)$data;
209:         if (empty($data)) {
210:             return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
211:         }
212: 
213:         if (!isset($format)) {
214:             $format = sprintf(
215:                 '/(?<!%s)%s%%s%s/',
216:                 preg_quote($options['escape'], '/'),
217:                 str_replace('%', '%%', preg_quote($options['before'], '/')),
218:                 str_replace('%', '%%', preg_quote($options['after'], '/'))
219:             );
220:         }
221: 
222:         if (strpos($str, '?') !== false && is_numeric(key($data))) {
223:             $offset = 0;
224:             while (($pos = strpos($str, '?', $offset)) !== false) {
225:                 $val = array_shift($data);
226:                 $offset = $pos + strlen($val);
227:                 $str = substr_replace($str, $val, $pos, 1);
228:             }
229:             return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
230:         } else {
231:             asort($data);
232: 
233:             $hashKeys = array();
234:             foreach ($data as $key => $value) {
235:                 $hashKeys[] = crc32($key);
236:             }
237: 
238:             $tempData = array_combine(array_keys($data), array_values($hashKeys));
239:             krsort($tempData);
240:             foreach ($tempData as $key => $hashVal) {
241:                 $key = sprintf($format, preg_quote($key, '/'));
242:                 $str = preg_replace($key, $hashVal, $str);
243:             }
244:             $dataReplacements = array_combine($hashKeys, array_values($data));
245:             foreach ($dataReplacements as $tmpHash => $tmpValue) {
246:                 $tmpValue = (is_array($tmpValue)) ? '' : $tmpValue;
247:                 $str = str_replace($tmpHash, $tmpValue, $str);
248:             }
249:         }
250: 
251:         if (!isset($options['format']) && isset($options['before'])) {
252:             $str = str_replace($options['escape'] . $options['before'], $options['before'], $str);
253:         }
254:         return ($options['clean']) ? String::cleanInsert($str, $options) : $str;
255:     }
256: 
257: /**
258:  * Cleans up a String::insert() formatted string with given $options depending on the 'clean' key in
259:  * $options. The default method used is text but html is also available. The goal of this function
260:  * is to replace all whitespace and unneeded markup around placeholders that did not get replaced
261:  * by String::insert().
262:  *
263:  * @param string $str
264:  * @param string $options
265:  * @return string
266:  * @see String::insert()
267:  */
268:     public static function cleanInsert($str, $options) {
269:         $clean = $options['clean'];
270:         if (!$clean) {
271:             return $str;
272:         }
273:         if ($clean === true) {
274:             $clean = array('method' => 'text');
275:         }
276:         if (!is_array($clean)) {
277:             $clean = array('method' => $options['clean']);
278:         }
279:         switch ($clean['method']) {
280:             case 'html':
281:                 $clean = array_merge(array(
282:                     'word' => '[\w,.]+',
283:                     'andText' => true,
284:                     'replacement' => '',
285:                 ), $clean);
286:                 $kleenex = sprintf(
287:                     '/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
288:                     preg_quote($options['before'], '/'),
289:                     $clean['word'],
290:                     preg_quote($options['after'], '/')
291:                 );
292:                 $str = preg_replace($kleenex, $clean['replacement'], $str);
293:                 if ($clean['andText']) {
294:                     $options['clean'] = array('method' => 'text');
295:                     $str = String::cleanInsert($str, $options);
296:                 }
297:                 break;
298:             case 'text':
299:                 $clean = array_merge(array(
300:                     'word' => '[\w,.]+',
301:                     'gap' => '[\s]*(?:(?:and|or)[\s]*)?',
302:                     'replacement' => '',
303:                 ), $clean);
304: 
305:                 $kleenex = sprintf(
306:                     '/(%s%s%s%s|%s%s%s%s)/',
307:                     preg_quote($options['before'], '/'),
308:                     $clean['word'],
309:                     preg_quote($options['after'], '/'),
310:                     $clean['gap'],
311:                     $clean['gap'],
312:                     preg_quote($options['before'], '/'),
313:                     $clean['word'],
314:                     preg_quote($options['after'], '/')
315:                 );
316:                 $str = preg_replace($kleenex, $clean['replacement'], $str);
317:                 break;
318:         }
319:         return $str;
320:     }
321: 
322: /**
323:  * Wraps text to a specific width, can optionally wrap at word breaks.
324:  *
325:  * ### Options
326:  *
327:  * - `width` The width to wrap to.  Defaults to 72
328:  * - `wordWrap` Only wrap on words breaks (spaces) Defaults to true.
329:  * - `indent` String to indent with. Defaults to null.
330:  * - `indentAt` 0 based index to start indenting at. Defaults to 0.
331:  *
332:  * @param string $text Text the text to format.
333:  * @param array|integer $options Array of options to use, or an integer to wrap the text to.
334:  * @return string Formatted text.
335:  */
336:     public static function wrap($text, $options = array()) {
337:         if (is_numeric($options)) {
338:             $options = array('width' => $options);
339:         }
340:         $options += array('width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0);
341:         if ($options['wordWrap']) {
342:             $wrapped = wordwrap($text, $options['width'], "\n");
343:         } else {
344:             $wrapped = trim(chunk_split($text, $options['width'] - 1, "\n"));
345:         }
346:         if (!empty($options['indent'])) {
347:             $chunks = explode("\n", $wrapped);
348:             for ($i = $options['indentAt'], $len = count($chunks); $i < $len; $i++) {
349:                 $chunks[$i] = $options['indent'] . $chunks[$i];
350:             }
351:             $wrapped = implode("\n", $chunks);
352:         }
353:         return $wrapped;
354:     }
355: 
356: /**
357:  * Highlights a given phrase in a text. You can specify any expression in highlighter that
358:  * may include the \1 expression to include the $phrase found.
359:  *
360:  * ### Options:
361:  *
362:  * - `format` The piece of html with that the phrase will be highlighted
363:  * - `html` If true, will ignore any HTML tags, ensuring that only the correct text is highlighted
364:  * - `regex` a custom regex rule that is ued to match words, default is '|$tag|iu'
365:  *
366:  * @param string $text Text to search the phrase in
367:  * @param string $phrase The phrase that will be searched
368:  * @param array $options An array of html attributes and options.
369:  * @return string The highlighted text
370:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
371:  */
372:     public static function highlight($text, $phrase, $options = array()) {
373:         if (empty($phrase)) {
374:             return $text;
375:         }
376: 
377:         $default = array(
378:             'format' => '<span class="highlight">\1</span>',
379:             'html' => false,
380:             'regex' => "|%s|iu"
381:         );
382:         $options = array_merge($default, $options);
383:         extract($options);
384: 
385:         if (is_array($phrase)) {
386:             $replace = array();
387:             $with = array();
388: 
389:             foreach ($phrase as $key => $segment) {
390:                 $segment = '(' . preg_quote($segment, '|') . ')';
391:                 if ($html) {
392:                     $segment = "(?![^<]+>)$segment(?![^<]+>)";
393:                 }
394: 
395:                 $with[] = (is_array($format)) ? $format[$key] : $format;
396:                 $replace[] = sprintf($options['regex'], $segment);
397:             }
398: 
399:             return preg_replace($replace, $with, $text);
400:         } else {
401:             $phrase = '(' . preg_quote($phrase, '|') . ')';
402:             if ($html) {
403:                 $phrase = "(?![^<]+>)$phrase(?![^<]+>)";
404:             }
405: 
406:             return preg_replace(sprintf($options['regex'], $phrase), $format, $text);
407:         }
408:     }
409: 
410: /**
411:  * Strips given text of all links (<a href=....)
412:  *
413:  * @param string $text Text
414:  * @return string The text without links
415:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
416:  */
417:     public static function stripLinks($text) {
418:         return preg_replace('|<a\s+[^>]+>|im', '', preg_replace('|<\/a>|im', '', $text));
419:     }
420: 
421: /**
422:  * Truncates text.
423:  *
424:  * Cuts a string to the length of $length and replaces the last characters
425:  * with the ending if the text is longer than length.
426:  *
427:  * ### Options:
428:  *
429:  * - `ending` Will be used as Ending and appended to the trimmed string
430:  * - `exact` If false, $text will not be cut mid-word
431:  * - `html` If true, HTML tags would be handled correctly
432:  *
433:  * @param string $text String to truncate.
434:  * @param integer $length Length of returned string, including ellipsis.
435:  * @param array $options An array of html attributes and options.
436:  * @return string Trimmed string.
437:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
438:  */
439:     public static function truncate($text, $length = 100, $options = array()) {
440:         $default = array(
441:             'ending' => '...', 'exact' => true, 'html' => false
442:         );
443:         $options = array_merge($default, $options);
444:         extract($options);
445: 
446:         if (!function_exists('mb_strlen')) {
447:             class_exists('Multibyte');
448:         }
449: 
450:         if ($html) {
451:             if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
452:                 return $text;
453:             }
454:             $totalLength = mb_strlen(strip_tags($ending));
455:             $openTags = array();
456:             $truncate = '';
457: 
458:             preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
459:             foreach ($tags as $tag) {
460:                 if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
461:                     if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
462:                         array_unshift($openTags, $tag[2]);
463:                     } elseif (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
464:                         $pos = array_search($closeTag[1], $openTags);
465:                         if ($pos !== false) {
466:                             array_splice($openTags, $pos, 1);
467:                         }
468:                     }
469:                 }
470:                 $truncate .= $tag[1];
471: 
472:                 $contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
473:                 if ($contentLength + $totalLength > $length) {
474:                     $left = $length - $totalLength;
475:                     $entitiesLength = 0;
476:                     if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
477:                         foreach ($entities[0] as $entity) {
478:                             if ($entity[1] + 1 - $entitiesLength <= $left) {
479:                                 $left--;
480:                                 $entitiesLength += mb_strlen($entity[0]);
481:                             } else {
482:                                 break;
483:                             }
484:                         }
485:                     }
486: 
487:                     $truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
488:                     break;
489:                 } else {
490:                     $truncate .= $tag[3];
491:                     $totalLength += $contentLength;
492:                 }
493:                 if ($totalLength >= $length) {
494:                     break;
495:                 }
496:             }
497:         } else {
498:             if (mb_strlen($text) <= $length) {
499:                 return $text;
500:             } else {
501:                 $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
502:             }
503:         }
504:         if (!$exact) {
505:             $spacepos = mb_strrpos($truncate, ' ');
506:             if ($html) {
507:                 $truncateCheck = mb_substr($truncate, 0, $spacepos);
508:                 $lastOpenTag = mb_strrpos($truncateCheck, '<');
509:                 $lastCloseTag = mb_strrpos($truncateCheck, '>');
510:                 if ($lastOpenTag > $lastCloseTag) {
511:                     preg_match_all('/<[\w]+[^>]*>/s', $truncate, $lastTagMatches);
512:                     $lastTag = array_pop($lastTagMatches[0]);
513:                     $spacepos = mb_strrpos($truncate, $lastTag) + mb_strlen($lastTag);
514:                 }
515:                 $bits = mb_substr($truncate, $spacepos);
516:                 preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
517:                 if (!empty($droppedTags)) {
518:                     if (!empty($openTags)) {
519:                         foreach ($droppedTags as $closingTag) {
520:                             if (!in_array($closingTag[1], $openTags)) {
521:                                 array_unshift($openTags, $closingTag[1]);
522:                             }
523:                         }
524:                     } else {
525:                         foreach ($droppedTags as $closingTag) {
526:                             $openTags[] = $closingTag[1];
527:                         }
528:                     }
529:                 }
530:             }
531:             $truncate = mb_substr($truncate, 0, $spacepos);
532:         }
533:         $truncate .= $ending;
534: 
535:         if ($html) {
536:             foreach ($openTags as $tag) {
537:                 $truncate .= '</' . $tag . '>';
538:             }
539:         }
540: 
541:         return $truncate;
542:     }
543: 
544: /**
545:  * Extracts an excerpt from the text surrounding the phrase with a number of characters on each side
546:  * determined by radius.
547:  *
548:  * @param string $text String to search the phrase in
549:  * @param string $phrase Phrase that will be searched for
550:  * @param integer $radius The amount of characters that will be returned on each side of the founded phrase
551:  * @param string $ending Ending that will be appended
552:  * @return string Modified string
553:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
554:  */
555:     public static function excerpt($text, $phrase, $radius = 100, $ending = '...') {
556:         if (empty($text) || empty($phrase)) {
557:             return self::truncate($text, $radius * 2, array('ending' => $ending));
558:         }
559: 
560:         $append = $prepend = $ending;
561: 
562:         $phraseLen = mb_strlen($phrase);
563:         $textLen = mb_strlen($text);
564: 
565:         $pos = mb_strpos(mb_strtolower($text), mb_strtolower($phrase));
566:         if ($pos === false) {
567:             return mb_substr($text, 0, $radius) . $ending;
568:         }
569: 
570:         $startPos = $pos - $radius;
571:         if ($startPos <= 0) {
572:             $startPos = 0;
573:             $prepend = '';
574:         }
575: 
576:         $endPos = $pos + $phraseLen + $radius;
577:         if ($endPos >= $textLen) {
578:             $endPos = $textLen;
579:             $append = '';
580:         }
581: 
582:         $excerpt = mb_substr($text, $startPos, $endPos - $startPos);
583:         $excerpt = $prepend . $excerpt . $append;
584: 
585:         return $excerpt;
586:     }
587: 
588: /**
589:  * Creates a comma separated list where the last two items are joined with 'and', forming natural English
590:  *
591:  * @param array $list The list to be joined
592:  * @param string $and The word used to join the last and second last items together with. Defaults to 'and'
593:  * @param string $separator The separator used to join all the other items together. Defaults to ', '
594:  * @return string The glued together string.
595:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
596:  */
597:     public static function toList($list, $and = 'and', $separator = ', ') {
598:         if (count($list) > 1) {
599:             return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list);
600:         } else {
601:             return array_pop($list);
602:         }
603:     }
604: 
605: }
606: 
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