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

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.3
      • 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:  * CakeTime utility class file.
   4:  *
   5:  * PHP 5
   6:  *
   7:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
   8:  * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
   9:  *
  10:  * Licensed under The MIT License
  11:  * For full copyright and license information, please see the LICENSE.txt
  12:  * Redistributions of files must retain the above copyright notice.
  13:  *
  14:  * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  15:  * @link          http://cakephp.org CakePHP(tm) Project
  16:  * @package       Cake.Utility
  17:  * @since         CakePHP(tm) v 0.10.0.1076
  18:  * @license       http://www.opensource.org/licenses/mit-license.php MIT License
  19:  */
  20: 
  21: App::uses('Multibyte', 'I18n');
  22: 
  23: /**
  24:  * Time Helper class for easy use of time data.
  25:  *
  26:  * Manipulation of time data.
  27:  *
  28:  * @package       Cake.Utility
  29:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html
  30:  */
  31: class CakeTime {
  32: 
  33: /**
  34:  * The format to use when formatting a time using `CakeTime::nice()`
  35:  *
  36:  * The format should use the locale strings as defined in the PHP docs under
  37:  * `strftime` (http://php.net/manual/en/function.strftime.php)
  38:  *
  39:  * @var string
  40:  * @see CakeTime::format()
  41:  */
  42:     public static $niceFormat = '%a, %b %eS %Y, %H:%M';
  43: 
  44: /**
  45:  * The format to use when formatting a time using `CakeTime::timeAgoInWords()`
  46:  * and the difference is more than `CakeTime::$wordEnd`
  47:  *
  48:  * @var string
  49:  * @see CakeTime::timeAgoInWords()
  50:  */
  51:     public static $wordFormat = 'j/n/y';
  52: 
  53: /**
  54:  * The format to use when formatting a time using `CakeTime::niceShort()`
  55:  * and the difference is between 3 and 7 days
  56:  *
  57:  * @var string
  58:  * @see CakeTime::niceShort()
  59:  */
  60:     public static $niceShortFormat = '%B %d, %H:%M';
  61: 
  62: /**
  63:  * The format to use when formatting a time using `CakeTime::timeAgoInWords()`
  64:  * and the difference is less than `CakeTime::$wordEnd`
  65:  *
  66:  * @var array
  67:  * @see CakeTime::timeAgoInWords()
  68:  */
  69:     public static $wordAccuracy = array(
  70:         'year' => "day",
  71:         'month' => "day",
  72:         'week' => "day",
  73:         'day' => "hour",
  74:         'hour' => "minute",
  75:         'minute' => "minute",
  76:         'second' => "second",
  77:     );
  78: 
  79: /**
  80:  * The end of relative time telling
  81:  *
  82:  * @var string
  83:  * @see CakeTime::timeAgoInWords()
  84:  */
  85:     public static $wordEnd = '+1 month';
  86: 
  87: /**
  88:  * Temporary variable containing timestamp value, used internally convertSpecifiers()
  89:  *
  90:  * @var integer
  91:  */
  92:     protected static $_time = null;
  93: 
  94: /**
  95:  * Magic set method for backward compatibility.
  96:  * Used by TimeHelper to modify static variables in CakeTime
  97:  *
  98:  * @param string $name Variable name
  99:  * @param mixes $value Variable value
 100:  * @return void
 101:  */
 102:     public function __set($name, $value) {
 103:         switch ($name) {
 104:             case 'niceFormat':
 105:                 self::${$name} = $value;
 106:                 break;
 107:         }
 108:     }
 109: 
 110: /**
 111:  * Magic set method for backward compatibility.
 112:  * Used by TimeHelper to get static variables in CakeTime
 113:  *
 114:  * @param string $name Variable name
 115:  * @return mixed
 116:  */
 117:     public function __get($name) {
 118:         switch ($name) {
 119:             case 'niceFormat':
 120:                 return self::${$name};
 121:             default:
 122:                 return null;
 123:         }
 124:     }
 125: 
 126: /**
 127:  * Converts a string representing the format for the function strftime and returns a
 128:  * windows safe and i18n aware format.
 129:  *
 130:  * @param string $format Format with specifiers for strftime function.
 131:  *    Accepts the special specifier %S which mimics the modifier S for date()
 132:  * @param string $time UNIX timestamp
 133:  * @return string windows safe and date() function compatible format for strftime
 134:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 135:  */
 136:     public static function convertSpecifiers($format, $time = null) {
 137:         if (!$time) {
 138:             $time = time();
 139:         }
 140:         self::$_time = $time;
 141:         return preg_replace_callback('/\%(\w+)/', array('CakeTime', '_translateSpecifier'), $format);
 142:     }
 143: 
 144: /**
 145:  * Auxiliary function to translate a matched specifier element from a regular expression into
 146:  * a windows safe and i18n aware specifier
 147:  *
 148:  * @param array $specifier match from regular expression
 149:  * @return string converted element
 150:  */
 151:     protected static function _translateSpecifier($specifier) {
 152:         switch ($specifier[1]) {
 153:             case 'a':
 154:                 $abday = __dc('cake', 'abday', 5);
 155:                 if (is_array($abday)) {
 156:                     return $abday[date('w', self::$_time)];
 157:                 }
 158:                 break;
 159:             case 'A':
 160:                 $day = __dc('cake', 'day', 5);
 161:                 if (is_array($day)) {
 162:                     return $day[date('w', self::$_time)];
 163:                 }
 164:                 break;
 165:             case 'c':
 166:                 $format = __dc('cake', 'd_t_fmt', 5);
 167:                 if ($format !== 'd_t_fmt') {
 168:                     return self::convertSpecifiers($format, self::$_time);
 169:                 }
 170:                 break;
 171:             case 'C':
 172:                 return sprintf("%02d", date('Y', self::$_time) / 100);
 173:             case 'D':
 174:                 return '%m/%d/%y';
 175:             case 'e':
 176:                 if (DS === '/') {
 177:                     return '%e';
 178:                 }
 179:                 $day = date('j', self::$_time);
 180:                 if ($day < 10) {
 181:                     $day = ' ' . $day;
 182:                 }
 183:                 return $day;
 184:             case 'eS' :
 185:                 return date('jS', self::$_time);
 186:             case 'b':
 187:             case 'h':
 188:                 $months = __dc('cake', 'abmon', 5);
 189:                 if (is_array($months)) {
 190:                     return $months[date('n', self::$_time) - 1];
 191:                 }
 192:                 return '%b';
 193:             case 'B':
 194:                 $months = __dc('cake', 'mon', 5);
 195:                 if (is_array($months)) {
 196:                     return $months[date('n', self::$_time) - 1];
 197:                 }
 198:                 break;
 199:             case 'n':
 200:                 return "\n";
 201:             case 'p':
 202:             case 'P':
 203:                 $default = array('am' => 0, 'pm' => 1);
 204:                 $meridiem = $default[date('a', self::$_time)];
 205:                 $format = __dc('cake', 'am_pm', 5);
 206:                 if (is_array($format)) {
 207:                     $meridiem = $format[$meridiem];
 208:                     return ($specifier[1] === 'P') ? strtolower($meridiem) : strtoupper($meridiem);
 209:                 }
 210:                 break;
 211:             case 'r':
 212:                 $complete = __dc('cake', 't_fmt_ampm', 5);
 213:                 if ($complete !== 't_fmt_ampm') {
 214:                     return str_replace('%p', self::_translateSpecifier(array('%p', 'p')), $complete);
 215:                 }
 216:                 break;
 217:             case 'R':
 218:                 return date('H:i', self::$_time);
 219:             case 't':
 220:                 return "\t";
 221:             case 'T':
 222:                 return '%H:%M:%S';
 223:             case 'u':
 224:                 return ($weekDay = date('w', self::$_time)) ? $weekDay : 7;
 225:             case 'x':
 226:                 $format = __dc('cake', 'd_fmt', 5);
 227:                 if ($format !== 'd_fmt') {
 228:                     return self::convertSpecifiers($format, self::$_time);
 229:                 }
 230:                 break;
 231:             case 'X':
 232:                 $format = __dc('cake', 't_fmt', 5);
 233:                 if ($format !== 't_fmt') {
 234:                     return self::convertSpecifiers($format, self::$_time);
 235:                 }
 236:                 break;
 237:         }
 238:         return $specifier[0];
 239:     }
 240: 
 241: /**
 242:  * Converts given time (in server's time zone) to user's local time, given his/her timezone.
 243:  *
 244:  * @param string $serverTime UNIX timestamp
 245:  * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object
 246:  * @return integer UNIX timestamp
 247:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 248:  */
 249:     public static function convert($serverTime, $timezone) {
 250:         static $serverTimezone = null;
 251:         if ($serverTimezone === null || (date_default_timezone_get() !== $serverTimezone->getName())) {
 252:             $serverTimezone = new DateTimeZone(date_default_timezone_get());
 253:         }
 254:         $serverOffset = $serverTimezone->getOffset(new DateTime('@' . $serverTime));
 255:         $gmtTime = $serverTime - $serverOffset;
 256:         if (is_numeric($timezone)) {
 257:             $userOffset = $timezone * (60 * 60);
 258:         } else {
 259:             $timezone = self::timezone($timezone);
 260:             $userOffset = $timezone->getOffset(new DateTime('@' . $gmtTime));
 261:         }
 262:         $userTime = $gmtTime + $userOffset;
 263:         return (int)$userTime;
 264:     }
 265: 
 266: /**
 267:  * Returns a timezone object from a string or the user's timezone object
 268:  *
 269:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 270:  *  If null it tries to get timezone from 'Config.timezone' config var
 271:  * @return DateTimeZone Timezone object
 272:  */
 273:     public static function timezone($timezone = null) {
 274:         static $tz = null;
 275: 
 276:         if (is_object($timezone)) {
 277:             if ($tz === null || $tz->getName() !== $timezone->getName()) {
 278:                 $tz = $timezone;
 279:             }
 280:         } else {
 281:             if ($timezone === null) {
 282:                 $timezone = Configure::read('Config.timezone');
 283:                 if ($timezone === null) {
 284:                     $timezone = date_default_timezone_get();
 285:                 }
 286:             }
 287: 
 288:             if ($tz === null || $tz->getName() !== $timezone) {
 289:                 $tz = new DateTimeZone($timezone);
 290:             }
 291:         }
 292: 
 293:         return $tz;
 294:     }
 295: 
 296: /**
 297:  * Returns server's offset from GMT in seconds.
 298:  *
 299:  * @return integer Offset
 300:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 301:  */
 302:     public static function serverOffset() {
 303:         return date('Z', time());
 304:     }
 305: 
 306: /**
 307:  * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
 308:  *
 309:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 310:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 311:  * @return string Parsed timestamp
 312:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 313:  */
 314:     public static function fromString($dateString, $timezone = null) {
 315:         if (empty($dateString)) {
 316:             return false;
 317:         }
 318: 
 319:         $containsDummyDate = (is_string($dateString) && substr($dateString, 0, 10) === '0000-00-00');
 320:         if ($containsDummyDate) {
 321:             return false;
 322:         }
 323: 
 324:         if (is_int($dateString) || is_numeric($dateString)) {
 325:             $date = intval($dateString);
 326:         } elseif (
 327:             $dateString instanceof DateTime &&
 328:             $dateString->getTimezone()->getName() != date_default_timezone_get()
 329:         ) {
 330:             $clone = clone $dateString;
 331:             $clone->setTimezone(new DateTimeZone(date_default_timezone_get()));
 332:             $date = (int)$clone->format('U') + $clone->getOffset();
 333:         } elseif ($dateString instanceof DateTime) {
 334:             $date = (int)$dateString->format('U');
 335:         } else {
 336:             $date = strtotime($dateString);
 337:         }
 338: 
 339:         if ($date === -1 || empty($date)) {
 340:             return false;
 341:         }
 342: 
 343:         if ($timezone === null) {
 344:             $timezone = Configure::read('Config.timezone');
 345:         }
 346: 
 347:         if ($timezone !== null) {
 348:             return self::convert($date, $timezone);
 349:         }
 350:         return $date;
 351:     }
 352: 
 353: /**
 354:  * Returns a nicely formatted date string for given Datetime string.
 355:  *
 356:  * See http://php.net/manual/en/function.strftime.php for information on formatting
 357:  * using locale strings.
 358:  *
 359:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 360:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 361:  * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used
 362:  * @return string Formatted date string
 363:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 364:  */
 365:     public static function nice($dateString = null, $timezone = null, $format = null) {
 366:         if (!$dateString) {
 367:             $dateString = time();
 368:         }
 369:         $date = self::fromString($dateString, $timezone);
 370: 
 371:         if (!$format) {
 372:             $format = self::$niceFormat;
 373:         }
 374:         return self::_strftime(self::convertSpecifiers($format, $date), $date);
 375:     }
 376: 
 377: /**
 378:  * Returns a formatted descriptive date string for given datetime string.
 379:  *
 380:  * If the given date is today, the returned string could be "Today, 16:54".
 381:  * If the given date is tomorrow, the returned string could be "Tomorrow, 16:54".
 382:  * If the given date was yesterday, the returned string could be "Yesterday, 16:54".
 383:  * If the given date is within next or last week, the returned string could be "On Thursday, 16:54".
 384:  * If $dateString's year is the current year, the returned string does not
 385:  * include mention of the year.
 386:  *
 387:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 388:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 389:  * @return string Described, relative date string
 390:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 391:  */
 392:     public static function niceShort($dateString = null, $timezone = null) {
 393:         if (!$dateString) {
 394:             $dateString = time();
 395:         }
 396:         $date = self::fromString($dateString, $timezone);
 397: 
 398:         if (self::isToday($dateString, $timezone)) {
 399:             return __d('cake', 'Today, %s', self::_strftime("%H:%M", $date));
 400:         }
 401:         if (self::wasYesterday($dateString, $timezone)) {
 402:             return __d('cake', 'Yesterday, %s', self::_strftime("%H:%M", $date));
 403:         }
 404:         if (self::isTomorrow($dateString, $timezone)) {
 405:             return __d('cake', 'Tomorrow, %s', self::_strftime("%H:%M", $date));
 406:         }
 407: 
 408:         $d = self::_strftime("%w", $date);
 409:         $day = array(
 410:             __d('cake', 'Sunday'),
 411:             __d('cake', 'Monday'),
 412:             __d('cake', 'Tuesday'),
 413:             __d('cake', 'Wednesday'),
 414:             __d('cake', 'Thursday'),
 415:             __d('cake', 'Friday'),
 416:             __d('cake', 'Saturday')
 417:         );
 418:         if (self::wasWithinLast('7 days', $dateString, $timezone)) {
 419:             return sprintf('%s %s', $day[$d], self::_strftime(self::$niceShortFormat, $date));
 420:         }
 421:         if (self::isWithinNext('7 days', $dateString, $timezone)) {
 422:             return __d('cake', 'On %s %s', $day[$d], self::_strftime(self::$niceShortFormat, $date));
 423:         }
 424: 
 425:         $y = '';
 426:         if (!self::isThisYear($date)) {
 427:             $y = ' %Y';
 428:         }
 429:         return self::_strftime(self::convertSpecifiers("%b %eS{$y}, %H:%M", $date), $date);
 430:     }
 431: 
 432: /**
 433:  * Returns a partial SQL string to search for all records between two dates.
 434:  *
 435:  * @param integer|string|DateTime $begin UNIX timestamp, strtotime() valid string or DateTime object
 436:  * @param integer|string|DateTime $end UNIX timestamp, strtotime() valid string or DateTime object
 437:  * @param string $fieldName Name of database field to compare with
 438:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 439:  * @return string Partial SQL string.
 440:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 441:  */
 442:     public static function daysAsSql($begin, $end, $fieldName, $timezone = null) {
 443:         $begin = self::fromString($begin, $timezone);
 444:         $end = self::fromString($end, $timezone);
 445:         $begin = date('Y-m-d', $begin) . ' 00:00:00';
 446:         $end = date('Y-m-d', $end) . ' 23:59:59';
 447: 
 448:         return "($fieldName >= '$begin') AND ($fieldName <= '$end')";
 449:     }
 450: 
 451: /**
 452:  * Returns a partial SQL string to search for all records between two times
 453:  * occurring on the same day.
 454:  *
 455:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 456:  * @param string $fieldName Name of database field to compare with
 457:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 458:  * @return string Partial SQL string.
 459:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 460:  */
 461:     public static function dayAsSql($dateString, $fieldName, $timezone = null) {
 462:         return self::daysAsSql($dateString, $dateString, $fieldName);
 463:     }
 464: 
 465: /**
 466:  * Returns true if given datetime string is today.
 467:  *
 468:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 469:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 470:  * @return boolean True if datetime string is today
 471:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 472:  */
 473:     public static function isToday($dateString, $timezone = null) {
 474:         $timestamp = self::fromString($dateString, $timezone);
 475:         $now = self::fromString('now', $timezone);
 476:         return date('Y-m-d', $timestamp) == date('Y-m-d', $now);
 477:     }
 478: 
 479: /**
 480:  * Returns true if given datetime string is within this week.
 481:  *
 482:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 483:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 484:  * @return boolean True if datetime string is within current week
 485:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 486:  */
 487:     public static function isThisWeek($dateString, $timezone = null) {
 488:         $timestamp = self::fromString($dateString, $timezone);
 489:         $now = self::fromString('now', $timezone);
 490:         return date('W o', $timestamp) == date('W o', $now);
 491:     }
 492: 
 493: /**
 494:  * Returns true if given datetime string is within this month
 495:  *
 496:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 497:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 498:  * @return boolean True if datetime string is within current month
 499:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 500:  */
 501:     public static function isThisMonth($dateString, $timezone = null) {
 502:         $timestamp = self::fromString($dateString, $timezone);
 503:         $now = self::fromString('now', $timezone);
 504:         return date('m Y', $timestamp) == date('m Y', $now);
 505:     }
 506: 
 507: /**
 508:  * Returns true if given datetime string is within current year.
 509:  *
 510:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 511:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 512:  * @return boolean True if datetime string is within current year
 513:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 514:  */
 515:     public static function isThisYear($dateString, $timezone = null) {
 516:         $timestamp = self::fromString($dateString, $timezone);
 517:         $now = self::fromString('now', $timezone);
 518:         return date('Y', $timestamp) == date('Y', $now);
 519:     }
 520: 
 521: /**
 522:  * Returns true if given datetime string was yesterday.
 523:  *
 524:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 525:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 526:  * @return boolean True if datetime string was yesterday
 527:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 528:  *
 529:  */
 530:     public static function wasYesterday($dateString, $timezone = null) {
 531:         $timestamp = self::fromString($dateString, $timezone);
 532:         $yesterday = self::fromString('yesterday', $timezone);
 533:         return date('Y-m-d', $timestamp) == date('Y-m-d', $yesterday);
 534:     }
 535: 
 536: /**
 537:  * Returns true if given datetime string is tomorrow.
 538:  *
 539:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 540:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 541:  * @return boolean True if datetime string was yesterday
 542:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 543:  */
 544:     public static function isTomorrow($dateString, $timezone = null) {
 545:         $timestamp = self::fromString($dateString, $timezone);
 546:         $tomorrow = self::fromString('tomorrow', $timezone);
 547:         return date('Y-m-d', $timestamp) == date('Y-m-d', $tomorrow);
 548:     }
 549: 
 550: /**
 551:  * Returns the quarter
 552:  *
 553:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 554:  * @param boolean $range if true returns a range in Y-m-d format
 555:  * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true
 556:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 557:  */
 558:     public static function toQuarter($dateString, $range = false) {
 559:         $time = self::fromString($dateString);
 560:         $date = ceil(date('m', $time) / 3);
 561:         if ($range === false) {
 562:             return $date;
 563:         }
 564: 
 565:         $year = date('Y', $time);
 566:         switch ($date) {
 567:             case 1:
 568:                 return array($year . '-01-01', $year . '-03-31');
 569:             case 2:
 570:                 return array($year . '-04-01', $year . '-06-30');
 571:             case 3:
 572:                 return array($year . '-07-01', $year . '-09-30');
 573:             case 4:
 574:                 return array($year . '-10-01', $year . '-12-31');
 575:         }
 576:     }
 577: 
 578: /**
 579:  * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
 580:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 581:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 582:  * @return integer Unix timestamp
 583:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 584:  */
 585:     public static function toUnix($dateString, $timezone = null) {
 586:         return self::fromString($dateString, $timezone);
 587:     }
 588: 
 589: /**
 590:  * Returns a formatted date in server's timezone.
 591:  *
 592:  * If a DateTime object is given or the dateString has a timezone
 593:  * segment, the timezone parameter will be ignored.
 594:  *
 595:  * If no timezone parameter is given and no DateTime object, the passed $dateString will be
 596:  * considered to be in the UTC timezone.
 597:  *
 598:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 599:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 600:  * @param string $format date format string
 601:  * @return mixed Formatted date
 602:  */
 603:     public static function toServer($dateString, $timezone = null, $format = 'Y-m-d H:i:s') {
 604:         if ($timezone === null) {
 605:             $timezone = new DateTimeZone('UTC');
 606:         } elseif (is_string($timezone)) {
 607:             $timezone = new DateTimeZone($timezone);
 608:         } elseif (!($timezone instanceof DateTimeZone)) {
 609:             return false;
 610:         }
 611: 
 612:         if ($dateString instanceof DateTime) {
 613:             $date = $dateString;
 614:         } elseif (is_int($dateString) || is_numeric($dateString)) {
 615:             $dateString = (int)$dateString;
 616: 
 617:             $date = new DateTime('@' . $dateString);
 618:             $date->setTimezone($timezone);
 619:         } else {
 620:             $date = new DateTime($dateString, $timezone);
 621:         }
 622: 
 623:         $date->setTimezone(new DateTimeZone(date_default_timezone_get()));
 624:         return $date->format($format);
 625:     }
 626: 
 627: /**
 628:  * Returns a date formatted for Atom RSS feeds.
 629:  *
 630:  * @param string $dateString Datetime string or Unix timestamp
 631:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 632:  * @return string Formatted date string
 633:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 634:  */
 635:     public static function toAtom($dateString, $timezone = null) {
 636:         return date('Y-m-d\TH:i:s\Z', self::fromString($dateString, $timezone));
 637:     }
 638: 
 639: /**
 640:  * Formats date for RSS feeds
 641:  *
 642:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 643:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 644:  * @return string Formatted date string
 645:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 646:  */
 647:     public static function toRSS($dateString, $timezone = null) {
 648:         $date = self::fromString($dateString, $timezone);
 649: 
 650:         if ($timezone === null) {
 651:             return date("r", $date);
 652:         }
 653: 
 654:         $userOffset = $timezone;
 655:         if (!is_numeric($timezone)) {
 656:             if (!is_object($timezone)) {
 657:                 $timezone = new DateTimeZone($timezone);
 658:             }
 659:             $currentDate = new DateTime('@' . $date);
 660:             $currentDate->setTimezone($timezone);
 661:             $userOffset = $timezone->getOffset($currentDate) / 60 / 60;
 662:         }
 663: 
 664:         $timezone = '+0000';
 665:         if ($userOffset != 0) {
 666:             $hours = (int)floor(abs($userOffset));
 667:             $minutes = (int)(fmod(abs($userOffset), $hours) * 60);
 668:             $timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT);
 669:         }
 670:         return date('D, d M Y H:i:s', $date) . ' ' . $timezone;
 671:     }
 672: 
 673: /**
 674:  * Returns either a relative date or a formatted date depending
 675:  * on the difference between the current time and given datetime.
 676:  * $datetime should be in a *strtotime* - parsable format, like MySQL's datetime datatype.
 677:  *
 678:  * ### Options:
 679:  *
 680:  * - `format` => a fall back format if the relative time is longer than the duration specified by end
 681:  * - `accuracy` => Specifies how accurate the date should be described (array)
 682:  *    - year =>   The format if years > 0   (default "day")
 683:  *    - month =>  The format if months > 0  (default "day")
 684:  *    - week =>   The format if weeks > 0   (default "day")
 685:  *    - day =>    The format if weeks > 0   (default "hour")
 686:  *    - hour =>   The format if hours > 0   (default "minute")
 687:  *    - minute => The format if minutes > 0 (default "minute")
 688:  *    - second => The format if seconds > 0 (default "second")
 689:  * - `end` => The end of relative time telling
 690:  * - `userOffset` => Users offset from GMT (in hours) *Deprecated* use timezone intead.
 691:  * - `timezone` => The user timezone the timestamp should be formatted in.
 692:  *
 693:  * Relative dates look something like this:
 694:  *
 695:  * - 3 weeks, 4 days ago
 696:  * - 15 seconds ago
 697:  *
 698:  * Default date formatting is d/m/yy e.g: on 18/2/09
 699:  *
 700:  * The returned string includes 'ago' or 'on' and assumes you'll properly add a word
 701:  * like 'Posted ' before the function output.
 702:  *
 703:  * NOTE: If the difference is one week or more, the lowest level of accuracy is day
 704:  *
 705:  * @param integer|string|DateTime $dateTime Datetime UNIX timestamp, strtotime() valid string or DateTime object
 706:  * @param array $options Default format if timestamp is used in $dateString
 707:  * @return string Relative time string.
 708:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 709:  */
 710:     public static function timeAgoInWords($dateTime, $options = array()) {
 711:         $timezone = null;
 712:         $format = self::$wordFormat;
 713:         $end = self::$wordEnd;
 714:         $accuracy = self::$wordAccuracy;
 715: 
 716:         if (is_array($options)) {
 717:             if (isset($options['timezone'])) {
 718:                 $timezone = $options['timezone'];
 719:             } elseif (isset($options['userOffset'])) {
 720:                 $timezone = $options['userOffset'];
 721:             }
 722: 
 723:             if (isset($options['accuracy'])) {
 724:                 if (is_array($options['accuracy'])) {
 725:                     $accuracy = array_merge($accuracy, $options['accuracy']);
 726:                 } else {
 727:                     foreach ($accuracy as $key => $level) {
 728:                         $accuracy[$key] = $options['accuracy'];
 729:                     }
 730:                 }
 731:             }
 732: 
 733:             if (isset($options['format'])) {
 734:                 $format = $options['format'];
 735:             }
 736:             if (isset($options['end'])) {
 737:                 $end = $options['end'];
 738:             }
 739:             unset($options['end'], $options['format']);
 740:         } else {
 741:             $format = $options;
 742:         }
 743: 
 744:         $now = self::fromString(time(), $timezone);
 745:         $inSeconds = self::fromString($dateTime, $timezone);
 746:         $backwards = ($inSeconds > $now);
 747: 
 748:         $futureTime = $now;
 749:         $pastTime = $inSeconds;
 750:         if ($backwards) {
 751:             $futureTime = $inSeconds;
 752:             $pastTime = $now;
 753:         }
 754:         $diff = $futureTime - $pastTime;
 755: 
 756:         // If more than a week, then take into account the length of months
 757:         if ($diff >= 604800) {
 758:             list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime));
 759: 
 760:             list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime));
 761:             $years = $months = $weeks = $days = $hours = $minutes = $seconds = 0;
 762: 
 763:             $years = $future['Y'] - $past['Y'];
 764:             $months = $future['m'] + ((12 * $years) - $past['m']);
 765: 
 766:             if ($months >= 12) {
 767:                 $years = floor($months / 12);
 768:                 $months = $months - ($years * 12);
 769:             }
 770:             if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] === 1) {
 771:                 $years--;
 772:             }
 773: 
 774:             if ($future['d'] >= $past['d']) {
 775:                 $days = $future['d'] - $past['d'];
 776:             } else {
 777:                 $daysInPastMonth = date('t', $pastTime);
 778:                 $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y']));
 779: 
 780:                 if (!$backwards) {
 781:                     $days = ($daysInPastMonth - $past['d']) + $future['d'];
 782:                 } else {
 783:                     $days = ($daysInFutureMonth - $past['d']) + $future['d'];
 784:                 }
 785: 
 786:                 if ($future['m'] != $past['m']) {
 787:                     $months--;
 788:                 }
 789:             }
 790: 
 791:             if (!$months && $years >= 1 && $diff < ($years * 31536000)) {
 792:                 $months = 11;
 793:                 $years--;
 794:             }
 795: 
 796:             if ($months >= 12) {
 797:                 $years = $years + 1;
 798:                 $months = $months - 12;
 799:             }
 800: 
 801:             if ($days >= 7) {
 802:                 $weeks = floor($days / 7);
 803:                 $days = $days - ($weeks * 7);
 804:             }
 805:         } else {
 806:             $years = $months = $weeks = 0;
 807:             $days = floor($diff / 86400);
 808: 
 809:             $diff = $diff - ($days * 86400);
 810: 
 811:             $hours = floor($diff / 3600);
 812:             $diff = $diff - ($hours * 3600);
 813: 
 814:             $minutes = floor($diff / 60);
 815:             $diff = $diff - ($minutes * 60);
 816:             $seconds = $diff;
 817:         }
 818:         $diff = $futureTime - $pastTime;
 819: 
 820:         if (!$diff) {
 821:             return __d('cake', 'just now', 'just now');
 822:         }
 823: 
 824:         if ($diff > abs($now - self::fromString($end))) {
 825:             return __d('cake', 'on %s', date($format, $inSeconds));
 826:         }
 827: 
 828:         $fWord = $accuracy['second'];
 829:         if ($years > 0) {
 830:             $fWord = $accuracy['year'];
 831:         } elseif (abs($months) > 0) {
 832:             $fWord = $accuracy['month'];
 833:         } elseif (abs($weeks) > 0) {
 834:             $fWord = $accuracy['week'];
 835:         } elseif (abs($days) > 0) {
 836:             $fWord = $accuracy['day'];
 837:         } elseif (abs($hours) > 0) {
 838:             $fWord = $accuracy['hour'];
 839:         } elseif (abs($minutes) > 0) {
 840:             $fWord = $accuracy['minute'];
 841:         }
 842: 
 843:         $fNum = str_replace(array('year', 'month', 'week', 'day', 'hour', 'minute', 'second'), array(1, 2, 3, 4, 5, 6, 7), $fWord);
 844: 
 845:         $relativeDate = '';
 846:         if ($fNum >= 1 && $years > 0) {
 847:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years);
 848:         }
 849:         if ($fNum >= 2 && $months > 0) {
 850:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months);
 851:         }
 852:         if ($fNum >= 3 && $weeks > 0) {
 853:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks);
 854:         }
 855:         if ($fNum >= 4 && $days > 0) {
 856:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days);
 857:         }
 858:         if ($fNum >= 5 && $hours > 0) {
 859:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours);
 860:         }
 861:         if ($fNum >= 6 && $minutes > 0) {
 862:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes);
 863:         }
 864:         if ($fNum >= 7 && $seconds > 0) {
 865:             $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds);
 866:         }
 867: 
 868:         $aboutAgo = array(
 869:             'second' => __d('cake', 'about a second ago'),
 870:             'minute' => __d('cake', 'about a minute ago'),
 871:             'hour' => __d('cake', 'about an hour ago'),
 872:             'day' => __d('cake', 'about a day ago'),
 873:             'week' => __d('cake', 'about a week ago'),
 874:             'year' => __d('cake', 'about a year ago')
 875:         );
 876: 
 877:         $aboutIn = array(
 878:             'second' => __d('cake', 'in about a second'),
 879:             'minute' => __d('cake', 'in about a minute'),
 880:             'hour' => __d('cake', 'in about an hour'),
 881:             'day' => __d('cake', 'in about a day'),
 882:             'week' => __d('cake', 'in about a week'),
 883:             'year' => __d('cake', 'in about a year')
 884:         );
 885: 
 886:         // When time has passed
 887:         if (!$backwards) {
 888:             if ($relativeDate) {
 889:                 return __d('cake', '%s ago', $relativeDate);
 890:             }
 891: 
 892:             return $aboutAgo[$fWord];
 893:         }
 894: 
 895:         // When time is to come
 896:         if (!$relativeDate) {
 897:             return $aboutIn[$fWord];
 898:         }
 899: 
 900:         return $relativeDate;
 901:     }
 902: 
 903: /**
 904:  * Returns true if specified datetime was within the interval specified, else false.
 905:  *
 906:  * @param string|integer $timeInterval the numeric value with space then time type.
 907:  *    Example of valid types: 6 hours, 2 days, 1 minute.
 908:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 909:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 910:  * @return boolean
 911:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 912:  */
 913:     public static function wasWithinLast($timeInterval, $dateString, $timezone = null) {
 914:         $tmp = str_replace(' ', '', $timeInterval);
 915:         if (is_numeric($tmp)) {
 916:             $timeInterval = $tmp . ' ' . __d('cake', 'days');
 917:         }
 918: 
 919:         $date = self::fromString($dateString, $timezone);
 920:         $interval = self::fromString('-' . $timeInterval);
 921:         $now = self::fromString('now', $timezone);
 922: 
 923:         return $date >= $interval && $date <= $now;
 924:     }
 925: 
 926: /**
 927:  * Returns true if specified datetime is within the interval specified, else false.
 928:  *
 929:  * @param string|integer $timeInterval the numeric value with space then time type.
 930:  *    Example of valid types: 6 hours, 2 days, 1 minute.
 931:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 932:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 933:  * @return boolean
 934:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
 935:  */
 936:     public static function isWithinNext($timeInterval, $dateString, $timezone = null) {
 937:         $tmp = str_replace(' ', '', $timeInterval);
 938:         if (is_numeric($tmp)) {
 939:             $timeInterval = $tmp . ' ' . __d('cake', 'days');
 940:         }
 941: 
 942:         $date = self::fromString($dateString, $timezone);
 943:         $interval = self::fromString('+' . $timeInterval);
 944:         $now = self::fromString('now', $timezone);
 945: 
 946:         return $date <= $interval && $date >= $now;
 947:     }
 948: 
 949: /**
 950:  * Returns gmt as a UNIX timestamp.
 951:  *
 952:  * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object
 953:  * @return integer UNIX timestamp
 954:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 955:  */
 956:     public static function gmt($dateString = null) {
 957:         $time = time();
 958:         if ($dateString) {
 959:             $time = self::fromString($dateString);
 960:         }
 961:         return gmmktime(
 962:             intval(date('G', $time)),
 963:             intval(date('i', $time)),
 964:             intval(date('s', $time)),
 965:             intval(date('n', $time)),
 966:             intval(date('j', $time)),
 967:             intval(date('Y', $time))
 968:         );
 969:     }
 970: 
 971: /**
 972:  * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
 973:  * This function also accepts a time string and a format string as first and second parameters.
 974:  * In that case this function behaves as a wrapper for TimeHelper::i18nFormat()
 975:  *
 976:  * ## Examples
 977:  *
 978:  * Create localized & formatted time:
 979:  *
 980:  * {{{
 981:  *   CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012
 982:  *   CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale
 983:  *   CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed
 984:  *   CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone
 985:  * }}}
 986:  *
 987:  * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string)
 988:  * @param integer|string|DateTime $format date format string (or UNIX timestamp, strtotime() valid string or DateTime object)
 989:  * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
 990:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
 991:  * @return string Formatted date string
 992:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
 993:  * @see CakeTime::i18nFormat()
 994:  */
 995:     public static function format($date, $format = null, $default = false, $timezone = null) {
 996:         //Backwards compatible params re-order test
 997:         $time = self::fromString($format, $timezone);
 998: 
 999:         if ($time === false) {
1000:             return self::i18nFormat($date, $format, $default, $timezone);
1001:         }
1002:         return date($date, $time);
1003:     }
1004: 
1005: /**
1006:  * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string.
1007:  * It take in account the default date format for the current language if a LC_TIME file is used.
1008:  *
1009:  * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object
1010:  * @param string $format strftime format string.
1011:  * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value
1012:  * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object
1013:  * @return string Formatted and translated date string
1014:  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
1015:  */
1016:     public static function i18nFormat($date, $format = null, $default = false, $timezone = null) {
1017:         $date = self::fromString($date, $timezone);
1018:         if ($date === false && $default !== false) {
1019:             return $default;
1020:         }
1021:         if (empty($format)) {
1022:             $format = '%x';
1023:         }
1024:         return self::_strftime(self::convertSpecifiers($format, $date), $date);
1025:     }
1026: 
1027: /**
1028:  * Get list of timezone identifiers
1029:  *
1030:  * @param integer|string $filter A regex to filter identifer
1031:  *  Or one of DateTimeZone class constants (PHP 5.3 and above)
1032:  * @param string $country A two-letter ISO 3166-1 compatible country code.
1033:  *  This option is only used when $filter is set to DateTimeZone::PER_COUNTRY (available only in PHP 5.3 and above)
1034:  * @param boolean $group If true (default value) groups the identifiers list by primary region
1035:  * @return array List of timezone identifiers
1036:  * @since 2.2
1037:  */
1038:     public static function listTimezones($filter = null, $country = null, $group = true) {
1039:         $regex = null;
1040:         if (is_string($filter)) {
1041:             $regex = $filter;
1042:             $filter = null;
1043:         }
1044:         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
1045:             if ($regex === null) {
1046:                 $regex = '#^((Africa|America|Antartica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/|UTC)#';
1047:             }
1048:             $identifiers = DateTimeZone::listIdentifiers();
1049:         } else {
1050:             if ($filter === null) {
1051:                 $filter = DateTimeZone::ALL;
1052:             }
1053:             $identifiers = DateTimeZone::listIdentifiers($filter, $country);
1054:         }
1055: 
1056:         if ($regex) {
1057:             foreach ($identifiers as $key => $tz) {
1058:                 if (!preg_match($regex, $tz)) {
1059:                     unset($identifiers[$key]);
1060:                 }
1061:             }
1062:         }
1063: 
1064:         if ($group) {
1065:             $return = array();
1066:             foreach ($identifiers as $key => $tz) {
1067:                 $item = explode('/', $tz, 2);
1068:                 if (isset($item[1])) {
1069:                     $return[$item[0]][$tz] = $item[1];
1070:                 } else {
1071:                     $return[$item[0]] = array($tz => $item[0]);
1072:                 }
1073:             }
1074:             return $return;
1075:         }
1076:         return array_combine($identifiers, $identifiers);
1077:     }
1078: 
1079: /**
1080:  * Multibyte wrapper for strftime.
1081:  *
1082:  * Handles utf8_encoding the result of strftime when necessary.
1083:  *
1084:  * @param string $format Format string.
1085:  * @param integer $date Timestamp to format.
1086:  * @return string formatted string with correct encoding.
1087:  */
1088:     protected static function _strftime($format, $date) {
1089:         $format = strftime($format, $date);
1090:         $encoding = Configure::read('App.encoding');
1091: 
1092:         if (!empty($encoding) && $encoding === 'UTF-8') {
1093:             if (function_exists('mb_check_encoding')) {
1094:                 $valid = mb_check_encoding($format, $encoding);
1095:             } else {
1096:                 $valid = !Multibyte::checkMultibyte($format);
1097:             }
1098:             if (!$valid) {
1099:                 $format = utf8_encode($format);
1100:             }
1101:         }
1102:         return $format;
1103:     }
1104: 
1105: }
1106: 
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