From 6dfd5d507d9863f987b30b0a5ab4268aea2ed875 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Thu, 2 Aug 2012 11:09:40 +0000 Subject: J'étais parti sur un download pourri de Cake. Les gars on abusé sur GitHub. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2012-php-weave/trunk@7 d972a294-176a-4cf9-8ea1-fcd5b0c30f5c --- .../lib/Cake/Utility/CakeNumber.php | 296 ++++++ .../lib/Cake/Utility/CakeTime.php | 1057 +++++++++++++++++++ .../lib/Cake/Utility/ClassRegistry.php | 368 +++++++ .../lib/Cake/Utility/Debugger.php | 817 +++++++++++++++ .../lib/Cake/Utility/File.php | 568 ++++++++++ .../lib/Cake/Utility/Folder.php | 780 ++++++++++++++ .../lib/Cake/Utility/Hash.php | 974 +++++++++++++++++ .../lib/Cake/Utility/Inflector.php | 551 ++++++++++ .../lib/Cake/Utility/ObjectCollection.php | 326 ++++++ .../lib/Cake/Utility/Sanitize.php | 264 +++++ .../lib/Cake/Utility/Security.php | 192 ++++ .../lib/Cake/Utility/Set.php | 1108 ++++++++++++++++++++ .../lib/Cake/Utility/String.php | 605 +++++++++++ .../lib/Cake/Utility/Validation.php | 937 +++++++++++++++++ .../lib/Cake/Utility/Xml.php | 370 +++++++ 15 files changed, 9213 insertions(+) create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Security.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Set.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/String.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Validation.php create mode 100644 poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Xml.php (limited to 'poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility') diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php new file mode 100644 index 0000000..3b21cbc --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeNumber.php @@ -0,0 +1,296 @@ + array( + 'wholeSymbol' => '$', 'wholePosition' => 'before', 'fractionSymbol' => 'c', 'fractionPosition' => 'after', + 'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()', 'escape' => true + ), + 'GBP' => array( + 'wholeSymbol' => '£', 'wholePosition' => 'before', 'fractionSymbol' => 'p', 'fractionPosition' => 'after', + 'zero' => 0, 'places' => 2, 'thousands' => ',', 'decimals' => '.', 'negative' => '()','escape' => false + ), + 'EUR' => array( + 'wholeSymbol' => '€', 'wholePosition' => 'before', 'fractionSymbol' => false, 'fractionPosition' => 'after', + 'zero' => 0, 'places' => 2, 'thousands' => '.', 'decimals' => ',', 'negative' => '()', 'escape' => false + ) + ); + +/** + * Default options for currency formats + * + * @var array + */ + protected static $_currencyDefaults = array( + 'wholeSymbol' => '', 'wholePosition' => 'before', 'fractionSymbol' => '', 'fractionPosition' => 'after', + 'zero' => '0', 'places' => 2, 'thousands' => ',', 'decimals' => '.','negative' => '()', 'escape' => true, + ); + +/** + * If native number_format() should be used. If >= PHP5.4 + * + * @var boolean + */ + protected static $_numberFormatSupport = null; + +/** + * Formats a number with a level of precision. + * + * @param float $number A floating point number. + * @param integer $precision The precision of the returned number. + * @return float Formatted float. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision + */ + public static function precision($number, $precision = 3) { + return sprintf("%01.{$precision}F", $number); + } + +/** + * Returns a formatted-for-humans file size. + * + * @param integer $size Size in bytes + * @return string Human readable size + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize + */ + public static function toReadableSize($size) { + switch (true) { + case $size < 1024: + return __dn('cake', '%d Byte', '%d Bytes', $size, $size); + case round($size / 1024) < 1024: + return __d('cake', '%d KB', self::precision($size / 1024, 0)); + case round($size / 1024 / 1024, 2) < 1024: + return __d('cake', '%.2f MB', self::precision($size / 1024 / 1024, 2)); + case round($size / 1024 / 1024 / 1024, 2) < 1024: + return __d('cake', '%.2f GB', self::precision($size / 1024 / 1024 / 1024, 2)); + default: + return __d('cake', '%.2f TB', self::precision($size / 1024 / 1024 / 1024 / 1024, 2)); + } + } + +/** + * Formats a number into a percentage string. + * + * @param float $number A floating point number + * @param integer $precision The precision of the returned number + * @return string Percentage string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage + */ + public static function toPercentage($number, $precision = 2) { + return self::precision($number, $precision) . '%'; + } + +/** + * Formats a number into a currency format. + * + * @param float $number A floating point number + * @param integer $options if int then places, if string then before, if (,.-) then use it + * or array with places and before keys + * @return string formatted number + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format + */ + public static function format($number, $options = false) { + $places = 0; + if (is_int($options)) { + $places = $options; + } + + $separators = array(',', '.', '-', ':'); + + $before = $after = null; + if (is_string($options) && !in_array($options, $separators)) { + $before = $options; + } + $thousands = ','; + if (!is_array($options) && in_array($options, $separators)) { + $thousands = $options; + } + $decimals = '.'; + if (!is_array($options) && in_array($options, $separators)) { + $decimals = $options; + } + + $escape = true; + if (is_array($options)) { + $options = array_merge(array('before' => '$', 'places' => 2, 'thousands' => ',', 'decimals' => '.'), $options); + extract($options); + } + + $out = $before . self::_numberFormat($number, $places, $decimals, $thousands) . $after; + + if ($escape) { + return h($out); + } + return $out; + } + +/** + * Alternative number_format() to accommodate multibyte decimals and thousands < PHP 5.4 + * + * @param float $number + * @param integer $places + * @param string $decimals + * @param string $thousands + * @return string + */ + protected static function _numberFormat($number, $places = 0, $decimals = '.', $thousands = ',') { + if (!isset(self::$_numberFormatSupport)) { + self::$_numberFormatSupport = version_compare(PHP_VERSION, '5.4.0', '>='); + } + if (self::$_numberFormatSupport) { + return number_format($number, $places, $decimals, $thousands); + } + $number = number_format($number, $places, '.', ''); + $after = ''; + $foundDecimal = strpos($number, '.'); + if ($foundDecimal !== false) { + $after = substr($number, $foundDecimal); + $number = substr($number, 0, $foundDecimal); + } + while (($foundThousand = preg_replace('/(\d+)(\d\d\d)/', '\1 \2', $number)) != $number) { + $number = $foundThousand; + } + $number .= $after; + return strtr($number, array(' ' => $thousands, '.' => $decimals)); + } + +/** + * Formats a number into a currency format. + * + * ### Options + * + * - `wholeSymbol` - The currency symbol to use for whole numbers, + * greater than 1, or less than -1. + * - `wholePosition` - The position the whole symbol should be placed + * valid options are 'before' & 'after'. + * - `fractionSymbol` - The currency symbol to use for fractional numbers. + * - `fractionPosition` - The position the fraction symbol should be placed + * valid options are 'before' & 'after'. + * - `before` - The currency symbol to place before whole numbers + * ie. '$'. `before` is an alias for `wholeSymbol`. + * - `after` - The currency symbol to place after decimal numbers + * ie. 'c'. Set to boolean false to use no decimal symbol. + * eg. 0.35 => $0.35. `after` is an alias for `fractionSymbol` + * - `zero` - The text to use for zero values, can be a + * string or a number. ie. 0, 'Free!' + * - `places` - Number of decimal places to use. ie. 2 + * - `thousands` - Thousands separator ie. ',' + * - `decimals` - Decimal separator symbol ie. '.' + * - `negative` - Symbol for negative numbers. If equal to '()', + * the number will be wrapped with ( and ) + * - `escape` - Should the output be htmlentity escaped? Defaults to true + * + * @param float $number + * @param string $currency Shortcut to default options. Valid values are + * 'USD', 'EUR', 'GBP', otherwise set at least 'before' and 'after' options. + * @param array $options + * @return string Number formatted as a currency. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency + */ + public static function currency($number, $currency = 'USD', $options = array()) { + $default = self::$_currencyDefaults; + + if (isset(self::$_currencies[$currency])) { + $default = self::$_currencies[$currency]; + } elseif (is_string($currency)) { + $options['before'] = $currency; + } + + $options = array_merge($default, $options); + + if (isset($options['before']) && $options['before'] !== '') { + $options['wholeSymbol'] = $options['before']; + } + if (isset($options['after']) && !$options['after'] !== '') { + $options['fractionSymbol'] = $options['after']; + } + + $result = $options['before'] = $options['after'] = null; + + $symbolKey = 'whole'; + if ($number == 0 ) { + if ($options['zero'] !== 0 ) { + return $options['zero']; + } + } elseif ($number < 1 && $number > -1 ) { + if ($options['fractionSymbol'] !== false) { + $multiply = intval('1' . str_pad('', $options['places'], '0')); + $number = $number * $multiply; + $options['places'] = null; + $symbolKey = 'fraction'; + } + } + + $position = $options[$symbolKey . 'Position'] != 'after' ? 'before' : 'after'; + $options[$position] = $options[$symbolKey . 'Symbol']; + + $abs = abs($number); + $result = self::format($abs, $options); + + if ($number < 0 ) { + if ($options['negative'] == '()') { + $result = '(' . $result . ')'; + } else { + $result = $options['negative'] . $result; + } + } + return $result; + } + +/** + * Add a currency format to the Number helper. Makes reusing + * currency formats easier. + * + * {{{ $number->addFormat('NOK', array('before' => 'Kr. ')); }}} + * + * You can now use `NOK` as a shortform when formatting currency amounts. + * + * {{{ $number->currency($value, 'NOK'); }}} + * + * Added formats are merged with the defaults defined in CakeNumber::$_currencyDefaults + * See CakeNumber::currency() for more information on the various options and their function. + * + * @param string $formatName The format name to be used in the future. + * @param array $options The array of options for this format. + * @return void + * @see NumberHelper::currency() + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat + */ + public static function addFormat($formatName, $options) { + self::$_currencies[$formatName] = $options + self::$_currencyDefaults; + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php new file mode 100644 index 0000000..4788d53 --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/CakeTime.php @@ -0,0 +1,1057 @@ + "day", + 'month' => "day", + 'week' => "day", + 'day' => "hour", + 'hour' => "minute", + 'minute' => "minute", + 'second' => "second", + ); + +/** + * The end of relative time telling + * + * @var string + * @see CakeTime::timeAgoInWords() + */ + public static $wordEnd = '+1 month'; + +/** + * Temporary variable containing timestamp value, used internally convertSpecifiers() + */ + protected static $_time = null; + +/** + * Magic set method for backward compatibility. + * + * Used by TimeHelper to modify static variables in CakeTime + */ + public function __set($name, $value) { + switch ($name) { + case 'niceFormat': + self::${$name} = $value; + break; + default: + break; + } + } + +/** + * Magic set method for backward compatibility. + * + * Used by TimeHelper to get static variables in CakeTime + */ + public function __get($name) { + switch ($name) { + case 'niceFormat': + return self::${$name}; + break; + default: + return null; + break; + } + } + +/** + * Converts a string representing the format for the function strftime and returns a + * windows safe and i18n aware format. + * + * @param string $format Format with specifiers for strftime function. + * Accepts the special specifier %S which mimics the modifier S for date() + * @param string $time UNIX timestamp + * @return string windows safe and date() function compatible format for strftime + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function convertSpecifiers($format, $time = null) { + if (!$time) { + $time = time(); + } + self::$_time = $time; + return preg_replace_callback('/\%(\w+)/', array('CakeTime', '_translateSpecifier'), $format); + } + +/** + * Auxiliary function to translate a matched specifier element from a regular expression into + * a windows safe and i18n aware specifier + * + * @param array $specifier match from regular expression + * @return string converted element + */ + protected static function _translateSpecifier($specifier) { + switch ($specifier[1]) { + case 'a': + $abday = __dc('cake', 'abday', 5); + if (is_array($abday)) { + return $abday[date('w', self::$_time)]; + } + break; + case 'A': + $day = __dc('cake', 'day', 5); + if (is_array($day)) { + return $day[date('w', self::$_time)]; + } + break; + case 'c': + $format = __dc('cake', 'd_t_fmt', 5); + if ($format != 'd_t_fmt') { + return self::convertSpecifiers($format, self::$_time); + } + break; + case 'C': + return sprintf("%02d", date('Y', self::$_time) / 100); + case 'D': + return '%m/%d/%y'; + case 'e': + if (DS === '/') { + return '%e'; + } + $day = date('j', self::$_time); + if ($day < 10) { + $day = ' ' . $day; + } + return $day; + case 'eS' : + return date('jS', self::$_time); + case 'b': + case 'h': + $months = __dc('cake', 'abmon', 5); + if (is_array($months)) { + return $months[date('n', self::$_time) - 1]; + } + return '%b'; + case 'B': + $months = __dc('cake', 'mon', 5); + if (is_array($months)) { + return $months[date('n', self::$_time) - 1]; + } + break; + case 'n': + return "\n"; + case 'p': + case 'P': + $default = array('am' => 0, 'pm' => 1); + $meridiem = $default[date('a', self::$_time)]; + $format = __dc('cake', 'am_pm', 5); + if (is_array($format)) { + $meridiem = $format[$meridiem]; + return ($specifier[1] == 'P') ? strtolower($meridiem) : strtoupper($meridiem); + } + break; + case 'r': + $complete = __dc('cake', 't_fmt_ampm', 5); + if ($complete != 't_fmt_ampm') { + return str_replace('%p', self::_translateSpecifier(array('%p', 'p')), $complete); + } + break; + case 'R': + return date('H:i', self::$_time); + case 't': + return "\t"; + case 'T': + return '%H:%M:%S'; + case 'u': + return ($weekDay = date('w', self::$_time)) ? $weekDay : 7; + case 'x': + $format = __dc('cake', 'd_fmt', 5); + if ($format != 'd_fmt') { + return self::convertSpecifiers($format, self::$_time); + } + break; + case 'X': + $format = __dc('cake', 't_fmt', 5); + if ($format != 't_fmt') { + return self::convertSpecifiers($format, self::$_time); + } + break; + } + return $specifier[0]; + } + +/** + * Converts given time (in server's time zone) to user's local time, given his/her timezone. + * + * @param string $serverTime UNIX timestamp + * @param string|DateTimeZone $timezone User's timezone string or DateTimeZone object + * @return integer UNIX timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function convert($serverTime, $timezone) { + static $serverTimezone = null; + if (is_null($serverTimezone) || (date_default_timezone_get() !== $serverTimezone->getName())) { + $serverTimezone = new DateTimeZone(date_default_timezone_get()); + } + $serverOffset = $serverTimezone->getOffset(new DateTime('@' . $serverTime)); + $gmtTime = $serverTime - $serverOffset; + if (is_numeric($timezone)) { + $userOffset = $timezone * (60 * 60); + } else { + $timezone = self::timezone($timezone); + $userOffset = $timezone->getOffset(new DateTime('@' . $gmtTime)); + } + $userTime = $gmtTime + $userOffset; + return (int)$userTime; + } + +/** + * Returns a timezone object from a string or the user's timezone object + * + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * If null it tries to get timezone from 'Config.timezone' config var + * @return DateTimeZone Timezone object + */ + public static function timezone($timezone = null) { + static $tz = null; + + if (is_object($timezone)) { + if ($tz === null || $tz->getName() !== $timezone->getName()) { + $tz = $timezone; + } + } else { + if ($timezone === null) { + $timezone = Configure::read('Config.timezone'); + if ($timezone === null) { + $timezone = date_default_timezone_get(); + } + } + + if ($tz === null || $tz->getName() !== $timezone) { + $tz = new DateTimeZone($timezone); + } + } + + return $tz; + } + +/** + * Returns server's offset from GMT in seconds. + * + * @return integer Offset + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function serverOffset() { + return date('Z', time()); + } + +/** + * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Parsed timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function fromString($dateString, $timezone = null) { + if (empty($dateString)) { + return false; + } + + if (is_integer($dateString) || is_numeric($dateString)) { + $date = intval($dateString); + } elseif (is_object($dateString) && $dateString instanceof DateTime) { + $clone = clone $dateString; + $clone->setTimezone(new DateTimeZone(date_default_timezone_get())); + $date = (int)$clone->format('U') + $clone->getOffset(); + } else { + $date = strtotime($dateString); + } + + if ($date === -1 || empty($date)) { + return false; + } + + if ($timezone === null) { + $timezone = Configure::read('Config.timezone'); + } + + if ($timezone !== null) { + return self::convert($date, $timezone); + } + return $date; + } + +/** + * Returns a nicely formatted date string for given Datetime string. + * + * See http://php.net/manual/en/function.strftime.php for information on formatting + * using locale strings. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @param string $format The format to use. If null, `TimeHelper::$niceFormat` is used + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function nice($dateString = null, $timezone = null, $format = null) { + if (!$dateString) { + $dateString = time(); + } + $date = self::fromString($dateString, $timezone); + + if (!$format) { + $format = self::$niceFormat; + } + $format = self::convertSpecifiers($format, $date); + return self::_strftime($format, $date); + } + +/** + * Returns a formatted descriptive date string for given datetime string. + * + * If the given date is today, the returned string could be "Today, 16:54". + * If the given date is tomorrow, the returned string could be "Tomorrow, 16:54". + * If the given date was yesterday, the returned string could be "Yesterday, 16:54". + * If the given date is within next or last week, the returned string could be "On Thursday, 16:54". + * If $dateString's year is the current year, the returned string does not + * include mention of the year. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Described, relative date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function niceShort($dateString = null, $timezone = null) { + if (!$dateString) { + $dateString = time(); + } + $date = self::fromString($dateString, $timezone); + + $y = self::isThisYear($date) ? '' : ' %Y'; + + $d = self::_strftime("%w", $date); + $day = array( + __d('cake', 'Sunday'), + __d('cake', 'Monday'), + __d('cake', 'Tuesday'), + __d('cake', 'Wednesday'), + __d('cake', 'Thursday'), + __d('cake', 'Friday'), + __d('cake', 'Saturday') + ); + + if (self::isToday($dateString, $timezone)) { + $ret = __d('cake', 'Today, %s', self::_strftime("%H:%M", $date)); + } elseif (self::wasYesterday($dateString, $timezone)) { + $ret = __d('cake', 'Yesterday, %s', self::_strftime("%H:%M", $date)); + } elseif (self::isTomorrow($dateString, $timezone)) { + $ret = __d('cake', 'Tomorrow, %s', self::_strftime("%H:%M", $date)); + } elseif (self::wasWithinLast('7 days', $dateString, $timezone)) { + $ret = sprintf('%s %s', $day[$d], self::_strftime(self::$niceShortFormat, $date)); + } elseif (self::isWithinNext('7 days', $dateString, $timezone)) { + $ret = __d('cake', 'On %s %s', $day[$d], self::_strftime(self::$niceShortFormat, $date)); + } else { + $format = self::convertSpecifiers("%b %eS{$y}, %H:%M", $date); + $ret = self::_strftime($format, $date); + } + return $ret; + } + +/** + * Returns a partial SQL string to search for all records between two dates. + * + * @param integer|string|DateTime $begin UNIX timestamp, strtotime() valid string or DateTime object + * @param integer|string|DateTime $end UNIX timestamp, strtotime() valid string or DateTime object + * @param string $fieldName Name of database field to compare with + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Partial SQL string. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function daysAsSql($begin, $end, $fieldName, $timezone = null) { + $begin = self::fromString($begin, $timezone); + $end = self::fromString($end, $timezone); + $begin = date('Y-m-d', $begin) . ' 00:00:00'; + $end = date('Y-m-d', $end) . ' 23:59:59'; + + return "($fieldName >= '$begin') AND ($fieldName <= '$end')"; + } + +/** + * Returns a partial SQL string to search for all records between two times + * occurring on the same day. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string $fieldName Name of database field to compare with + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Partial SQL string. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function dayAsSql($dateString, $fieldName, $timezone = null) { + return self::daysAsSql($dateString, $dateString, $fieldName); + } + +/** + * Returns true if given datetime string is today. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean True if datetime string is today + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function isToday($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + return date('Y-m-d', $date) == date('Y-m-d', time()); + } + +/** + * Returns true if given datetime string is within this week. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean True if datetime string is within current week + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function isThisWeek($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + return date('W o', $date) == date('W o', time()); + } + +/** + * Returns true if given datetime string is within this month + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean True if datetime string is within current month + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function isThisMonth($dateString, $timezone = null) { + $date = self::fromString($dateString); + return date('m Y', $date) == date('m Y', time()); + } + +/** + * Returns true if given datetime string is within current year. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean True if datetime string is within current year + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function isThisYear($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + return date('Y', $date) == date('Y', time()); + } + +/** + * Returns true if given datetime string was yesterday. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean True if datetime string was yesterday + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + * + */ + public static function wasYesterday($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday')); + } + +/** + * Returns true if given datetime string is tomorrow. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean True if datetime string was yesterday + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function isTomorrow($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow')); + } + +/** + * Returns the quarter + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param boolean $range if true returns a range in Y-m-d format + * @return mixed 1, 2, 3, or 4 quarter of year or array if $range true + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function toQuarter($dateString, $range = false) { + $time = self::fromString($dateString); + $date = ceil(date('m', $time) / 3); + + if ($range === true) { + $range = 'Y-m-d'; + } + + if ($range !== false) { + $year = date('Y', $time); + + switch ($date) { + case 1: + $date = array($year . '-01-01', $year . '-03-31'); + break; + case 2: + $date = array($year . '-04-01', $year . '-06-30'); + break; + case 3: + $date = array($year . '-07-01', $year . '-09-30'); + break; + case 4: + $date = array($year . '-10-01', $year . '-12-31'); + break; + } + } + return $date; + } + +/** + * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime(). + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return integer Unix timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function toUnix($dateString, $timezone = null) { + return self::fromString($dateString, $timezone); + } + +/** + * Returns a formatted date in server's timezone. + * + * If a DateTime object is given or the dateString has a timezone + * segment, the timezone parameter will be ignored. + * + * If no timezone parameter is given and no DateTime object, the passed $dateString will be + * considered to be in the UTC timezone. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @param string $format date format string + * @return mixed Formatted date + */ + public static function toServer($dateString, $timezone = null, $format = 'Y-m-d H:i:s') { + if ($timezone === null) { + $timezone = new DateTimeZone('UTC'); + } elseif (is_string($timezone)) { + $timezone = new DateTimeZone($timezone); + } elseif (!($timezone instanceof DateTimeZone)) { + return false; + } + + if ($dateString instanceof DateTime) { + $date = $dateString; + } elseif (is_integer($dateString) || is_numeric($dateString)) { + $dateString = (int)$dateString; + + $date = new DateTime('@' . $dateString); + $date->setTimezone($timezone); + } else { + $date = new DateTime($dateString, $timezone); + } + + $date->setTimezone(new DateTimeZone(date_default_timezone_get())); + return $date->format($format); + } + +/** + * Returns a date formatted for Atom RSS feeds. + * + * @param string $dateString Datetime string or Unix timestamp + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function toAtom($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + return date('Y-m-d\TH:i:s\Z', $date); + } + +/** + * Formats date for RSS feeds + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function toRSS($dateString, $timezone = null) { + $date = self::fromString($dateString, $timezone); + + if (!is_null($timezone)) { + if (is_numeric($timezone)) { + $userOffset = $timezone; + } else { + if (!is_object($timezone)) { + $timezone = new DateTimeZone($timezone); + } + $currentDate = new DateTime('@' . $date); + $currentDate->setTimezone($timezone); + $userOffset = $timezone->getOffset($currentDate) / 60 / 60; + } + if ($userOffset == 0) { + $timezone = '+0000'; + } else { + $hours = (int)floor(abs($userOffset)); + $minutes = (int)(fmod(abs($userOffset), $hours) * 60); + $timezone = ($userOffset < 0 ? '-' : '+') . str_pad($hours, 2, '0', STR_PAD_LEFT) . str_pad($minutes, 2, '0', STR_PAD_LEFT); + } + return date('D, d M Y H:i:s', $date) . ' ' . $timezone; + } + return date("r", $date); + } + +/** + * Returns either a relative date or a formatted date depending + * on the difference between the current time and given datetime. + * $datetime should be in a *strtotime* - parsable format, like MySQL's datetime datatype. + * + * ### Options: + * + * - `format` => a fall back format if the relative time is longer than the duration specified by end + * - `accuracy` => Specifies how accurate the date should be described (array) + * - year => The format if years > 0 (default "day") + * - month => The format if months > 0 (default "day") + * - week => The format if weeks > 0 (default "day") + * - day => The format if weeks > 0 (default "hour") + * - hour => The format if hours > 0 (default "minute") + * - minute => The format if minutes > 0 (default "minute") + * - second => The format if seconds > 0 (default "second") + * - `end` => The end of relative time telling + * - `userOffset` => Users offset from GMT (in hours) *Deprecated* use timezone intead. + * - `timezone` => The user timezone the timestamp should be formatted in. + * + * Relative dates look something like this: + * + * - 3 weeks, 4 days ago + * - 15 seconds ago + * + * Default date formatting is d/m/yy e.g: on 18/2/09 + * + * The returned string includes 'ago' or 'on' and assumes you'll properly add a word + * like 'Posted ' before the function output. + * + * NOTE: If the difference is one week or more, the lowest level of accuracy is day + * + * @param integer|string|DateTime $dateTime Datetime UNIX timestamp, strtotime() valid string or DateTime object + * @param array $options Default format if timestamp is used in $dateString + * @return string Relative time string. + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function timeAgoInWords($dateTime, $options = array()) { + $timezone = null; + $format = self::$wordFormat; + $end = self::$wordEnd; + $accuracy = self::$wordAccuracy; + + if (is_array($options)) { + if (isset($options['timezone'])) { + $timezone = $options['timezone']; + } elseif (isset($options['userOffset'])) { + $timezone = $options['userOffset']; + } + + if (isset($options['accuracy'])) { + if (is_array($options['accuracy'])) { + $accuracy = array_merge($accuracy, $options['accuracy']); + } else { + foreach ($accuracy as $key => $level) { + $accuracy[$key] = $options['accuracy']; + } + } + } + + if (isset($options['format'])) { + $format = $options['format']; + } + if (isset($options['end'])) { + $end = $options['end']; + } + unset($options['end'], $options['format']); + } else { + $format = $options; + } + + $now = self::fromString(time(), $timezone); + $inSeconds = self::fromString($dateTime, $timezone); + $backwards = ($inSeconds > $now); + + if ($backwards) { + $futureTime = $inSeconds; + $pastTime = $now; + } else { + $futureTime = $now; + $pastTime = $inSeconds; + } + $diff = $futureTime - $pastTime; + + // If more than a week, then take into account the length of months + if ($diff >= 604800) { + list($future['H'], $future['i'], $future['s'], $future['d'], $future['m'], $future['Y']) = explode('/', date('H/i/s/d/m/Y', $futureTime)); + + list($past['H'], $past['i'], $past['s'], $past['d'], $past['m'], $past['Y']) = explode('/', date('H/i/s/d/m/Y', $pastTime)); + $years = $months = $weeks = $days = $hours = $minutes = $seconds = 0; + + $years = $future['Y'] - $past['Y']; + $months = $future['m'] + ((12 * $years) - $past['m']); + + if ($months >= 12) { + $years = floor($months / 12); + $months = $months - ($years * 12); + } + if ($future['m'] < $past['m'] && $future['Y'] - $past['Y'] == 1) { + $years--; + } + + if ($future['d'] >= $past['d']) { + $days = $future['d'] - $past['d']; + } else { + $daysInPastMonth = date('t', $pastTime); + $daysInFutureMonth = date('t', mktime(0, 0, 0, $future['m'] - 1, 1, $future['Y'])); + + if (!$backwards) { + $days = ($daysInPastMonth - $past['d']) + $future['d']; + } else { + $days = ($daysInFutureMonth - $past['d']) + $future['d']; + } + + if ($future['m'] != $past['m']) { + $months--; + } + } + + if ($months == 0 && $years >= 1 && $diff < ($years * 31536000)) { + $months = 11; + $years--; + } + + if ($months >= 12) { + $years = $years + 1; + $months = $months - 12; + } + + if ($days >= 7) { + $weeks = floor($days / 7); + $days = $days - ($weeks * 7); + } + } else { + $years = $months = $weeks = 0; + $days = floor($diff / 86400); + + $diff = $diff - ($days * 86400); + + $hours = floor($diff / 3600); + $diff = $diff - ($hours * 3600); + + $minutes = floor($diff / 60); + $diff = $diff - ($minutes * 60); + $seconds = $diff; + } + $relativeDate = ''; + $diff = $futureTime - $pastTime; + + if ($diff > abs($now - self::fromString($end))) { + $relativeDate = __d('cake', 'on %s', date($format, $inSeconds)); + } else { + if ($years > 0) { + $f = $accuracy['year']; + } elseif (abs($months) > 0) { + $f = $accuracy['month']; + } elseif (abs($weeks) > 0) { + $f = $accuracy['week']; + } elseif (abs($days) > 0) { + $f = $accuracy['day']; + } elseif (abs($hours) > 0) { + $f = $accuracy['hour']; + } elseif (abs($minutes) > 0) { + $f = $accuracy['minute']; + } else { + $f = $accuracy['second']; + } + + $f = str_replace(array('year', 'month', 'week', 'day', 'hour', 'minute', 'second'), array(1, 2, 3, 4, 5, 6, 7), $f); + + $relativeDate .= $f >= 1 && $years > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years) : ''; + $relativeDate .= $f >= 2 && $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : ''; + $relativeDate .= $f >= 3 && $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : ''; + $relativeDate .= $f >= 4 && $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : ''; + $relativeDate .= $f >= 5 && $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : ''; + $relativeDate .= $f >= 6 && $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : ''; + $relativeDate .= $f >= 7 && $seconds > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds) : ''; + + if (!$backwards) { + $relativeDate = __d('cake', '%s ago', $relativeDate); + } + } + + // If now + if ($diff == 0) { + $relativeDate = __d('cake', 'just now', 'just now'); + } + return $relativeDate; + } + +/** + * Returns true if specified datetime was within the interval specified, else false. + * + * @param string|integer $timeInterval the numeric value with space then time type. + * Example of valid types: 6 hours, 2 days, 1 minute. + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function wasWithinLast($timeInterval, $dateString, $timezone = null) { + $tmp = str_replace(' ', '', $timeInterval); + if (is_numeric($tmp)) { + $timeInterval = $tmp . ' ' . __d('cake', 'days'); + } + + $date = self::fromString($dateString, $timezone); + $interval = self::fromString('-' . $timeInterval); + + if ($date >= $interval && $date <= time()) { + return true; + } + return false; + } + +/** + * Returns true if specified datetime is within the interval specified, else false. + * + * @param string|integer $timeInterval the numeric value with space then time type. + * Example of valid types: 6 hours, 2 days, 1 minute. + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return boolean + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time + */ + public static function isWithinNext($timeInterval, $dateString, $timezone = null) { + $tmp = str_replace(' ', '', $timeInterval); + if (is_numeric($tmp)) { + $timeInterval = $tmp . ' ' . __d('cake', 'days'); + } + + $date = self::fromString($dateString, $timezone); + $interval = self::fromString('+' . $timeInterval); + + if ($date <= $interval && $date >= time()) { + return true; + } + return false; + } + +/** + * Returns gmt as a UNIX timestamp. + * + * @param integer|string|DateTime $dateString UNIX timestamp, strtotime() valid string or DateTime object + * @return integer UNIX timestamp + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function gmt($dateString = null) { + if ($dateString != null) { + $time = self::fromString($dateString); + } else { + $time = time(); + } + $hour = intval(date("G", $time)); + $minute = intval(date("i", $time)); + $second = intval(date("s", $time)); + $month = intval(date("n", $time)); + $day = intval(date("j", $time)); + $year = intval(date("Y", $time)); + return gmmktime($hour, $minute, $second, $month, $day, $year); + } + +/** + * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string. + * This function also accepts a time string and a format string as first and second parameters. + * In that case this function behaves as a wrapper for TimeHelper::i18nFormat() + * + * ## Examples: + * {{{ + * CakeTime::format('2012-02-15', '%m-%d-%Y'); // returns 02-15-2012 + * CakeTime::format('2012-02-15 23:01:01', '%c'); // returns preferred date and time based on configured locale + * CakeTime::format('0000-00-00', '%d-%m-%Y', 'N/A'); // return N/A becuase an invalid date was passed + * CakeTime::format('2012-02-15 23:01:01', '%c', 'N/A', 'America/New_York'); // converts passed date to timezone + * }}} + * + * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object (or a date format string) + * @param integer|string|DateTime $format date format string (or UNIX timestamp, strtotime() valid string or DateTime object) + * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Formatted date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function format($date, $format = null, $default = false, $timezone = null) { + //Backwards compatible params order + $time = self::fromString($format, $timezone); + $_time = is_numeric($time) ? false : self::fromString($date, $timezone); + + if (is_numeric($_time) && $time === false) { + return self::i18nFormat($_time, $format, $default, $timezone); + } + if ($time === false && $default !== false) { + return $default; + } + return date($date, $time); + } + +/** + * Returns a formatted date string, given either a UNIX timestamp or a valid strtotime() date string. + * It take in account the default date format for the current language if a LC_TIME file is used. + * + * @param integer|string|DateTime $date UNIX timestamp, strtotime() valid string or DateTime object + * @param string $format strftime format string. + * @param boolean|string $default if an invalid date is passed it will output supplied default value. Pass false if you want raw conversion value + * @param string|DateTimeZone $timezone Timezone string or DateTimeZone object + * @return string Formatted and translated date string + * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting + */ + public static function i18nFormat($date, $format = null, $default = false, $timezone = null) { + $date = self::fromString($date, $timezone); + if ($date === false && $default !== false) { + return $default; + } + if (empty($format)) { + $format = '%x'; + } + $format = self::convertSpecifiers($format, $date); + return self::_strftime($format, $date); + } + +/** + * Get list of timezone identifiers + * + * @param integer|string $filter A regex to filter identifer + * Or one of DateTimeZone class constants (PHP 5.3 and above) + * @param string $country A two-letter ISO 3166-1 compatible country code. + * This option is only used when $filter is set to DateTimeZone::PER_COUNTRY (available only in PHP 5.3 and above) + * @param boolean $group If true (default value) groups the identifiers list by primary region + * @return array List of timezone identifiers + * @since 2.2 + */ + public static function listTimezones($filter = null, $country = null, $group = true) { + $regex = null; + if (is_string($filter)) { + $regex = $filter; + $filter = null; + } + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + if ($regex === null) { + $regex = '#^((Africa|America|Antartica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)/|UTC)#'; + } + $identifiers = DateTimeZone::listIdentifiers(); + } else { + if ($filter === null) { + $filter = DateTimeZone::ALL; + } + $identifiers = DateTimeZone::listIdentifiers($filter, $country); + } + + if ($regex) { + foreach ($identifiers as $key => $tz) { + if (!preg_match($regex, $tz)) { + unset($identifiers[$key]); + } + } + } + + if ($group) { + $return = array(); + foreach ($identifiers as $key => $tz) { + $item = explode('/', $tz, 2); + if (isset($item[1])) { + $return[$item[0]][$tz] = $item[1]; + } else { + $return[$item[0]] = array($tz => $item[0]); + } + } + return $return; + } else { + return array_combine($identifiers, $identifiers); + } + } + +/** + * Multibyte wrapper for strftime. + * + * Handles utf8_encoding the result of strftime when necessary. + * + * @param string $format Format string. + * @param integer $date Timestamp to format. + * @return string formatted string with correct encoding. + */ + protected static function _strftime($format, $date) { + $format = strftime($format, $date); + $encoding = Configure::read('App.encoding'); + + if (!empty($encoding) && $encoding === 'UTF-8') { + if (function_exists('mb_check_encoding')) { + $valid = mb_check_encoding($format, $encoding); + } else { + $valid = !Multibyte::checkMultibyte($format); + } + if (!$valid) { + $format = utf8_encode($format); + } + } + return $format; + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php new file mode 100644 index 0000000..da7b125 --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ClassRegistry.php @@ -0,0 +1,368 @@ + 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model');``` + * + * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);``` + * + * When $class is a numeric keyed array, multiple class instances will be stored in the registry, + * no instance of the object will be returned + * {{{ + * array( + * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry'), + * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry'), + * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry') + * ); + * }}} + * @param string|array $class as a string or a single key => value array instance will be created, + * stored in the registry and returned. + * @param boolean $strict if set to true it will return false if the class was not found instead + * of trying to create an AppModel + * @return object instance of ClassName. + * @throws CakeException when you try to construct an interface or abstract class. + */ + public static function init($class, $strict = false) { + $_this = ClassRegistry::getInstance(); + $false = false; + $true = true; + + if (is_array($class)) { + $objects = $class; + if (!isset($class[0])) { + $objects = array($class); + } + } else { + $objects = array(array('class' => $class)); + } + $defaults = isset($_this->_config['Model']) ? $_this->_config['Model'] : array(); + $count = count($objects); + $availableDs = array_keys(ConnectionManager::enumConnectionObjects()); + + foreach ($objects as $key => $settings) { + if (is_array($settings)) { + $pluginPath = null; + $settings = array_merge($defaults, $settings); + $class = $settings['class']; + + list($plugin, $class) = pluginSplit($class); + if ($plugin) { + $pluginPath = $plugin . '.'; + } + + if (empty($settings['alias'])) { + $settings['alias'] = $class; + } + $alias = $settings['alias']; + + if ($model = $_this->_duplicate($alias, $class)) { + $_this->map($alias, $class); + return $model; + } + + App::uses($plugin . 'AppModel', $pluginPath . 'Model'); + App::uses($class, $pluginPath . 'Model'); + + if (class_exists($class) || interface_exists($class)) { + $reflection = new ReflectionClass($class); + if ($reflection->isAbstract() || $reflection->isInterface()) { + throw new CakeException(__d('cake_dev', 'Cannot create instance of %s, as it is abstract or is an interface', $class)); + } + $testing = isset($settings['testing']) ? $settings['testing'] : false; + if ($testing) { + $settings['ds'] = 'test'; + $defaultProperties = $reflection->getDefaultProperties(); + if (isset($defaultProperties['useDbConfig'])) { + $useDbConfig = $defaultProperties['useDbConfig']; + if (in_array('test_' . $useDbConfig, $availableDs)) { + $useDbConfig = 'test_' . $useDbConfig; + } + if (strpos($useDbConfig, 'test') === 0) { + $settings['ds'] = $useDbConfig; + } + } + } + if ($reflection->getConstructor()) { + $instance = $reflection->newInstance($settings); + } else { + $instance = $reflection->newInstance(); + } + if ($strict) { + $instance = ($instance instanceof Model) ? $instance : null; + } + } + if (!isset($instance)) { + if ($strict) { + return false; + } elseif ($plugin && class_exists($plugin . 'AppModel')) { + $appModel = $plugin . 'AppModel'; + } else { + $appModel = 'AppModel'; + } + if (!empty($appModel)) { + $settings['name'] = $class; + $instance = new $appModel($settings); + } + + if (!isset($instance)) { + trigger_error(__d('cake_dev', '(ClassRegistry::init() could not create instance of %1$s class %2$s ', $class, $type), E_USER_WARNING); + return $false; + } + } + $_this->map($alias, $class); + } elseif (is_numeric($settings)) { + trigger_error(__d('cake_dev', '(ClassRegistry::init() Attempted to create instance of a class with a numeric name'), E_USER_WARNING); + return $false; + } + } + + if ($count > 1) { + return $true; + } + return $instance; + } + +/** + * Add $object to the registry, associating it with the name $key. + * + * @param string $key Key for the object in registry + * @param object $object Object to store + * @return boolean True if the object was written, false if $key already exists + */ + public static function addObject($key, $object) { + $_this = ClassRegistry::getInstance(); + $key = Inflector::underscore($key); + if (!isset($_this->_objects[$key])) { + $_this->_objects[$key] = $object; + return true; + } + return false; + } + +/** + * Remove object which corresponds to given key. + * + * @param string $key Key of object to remove from registry + * @return void + */ + public static function removeObject($key) { + $_this = ClassRegistry::getInstance(); + $key = Inflector::underscore($key); + if (isset($_this->_objects[$key])) { + unset($_this->_objects[$key]); + } + } + +/** + * Returns true if given key is present in the ClassRegistry. + * + * @param string $key Key to look for + * @return boolean true if key exists in registry, false otherwise + */ + public static function isKeySet($key) { + $_this = ClassRegistry::getInstance(); + $key = Inflector::underscore($key); + if (isset($_this->_objects[$key])) { + return true; + } elseif (isset($_this->_map[$key])) { + return true; + } + return false; + } + +/** + * Get all keys from the registry. + * + * @return array Set of keys stored in registry + */ + public static function keys() { + $_this = ClassRegistry::getInstance(); + return array_keys($_this->_objects); + } + +/** + * Return object which corresponds to given key. + * + * @param string $key Key of object to look for + * @return mixed Object stored in registry or boolean false if the object does not exist. + */ + public static function &getObject($key) { + $_this = ClassRegistry::getInstance(); + $key = Inflector::underscore($key); + $return = false; + if (isset($_this->_objects[$key])) { + $return = $_this->_objects[$key]; + } else { + $key = $_this->_getMap($key); + if (isset($_this->_objects[$key])) { + $return = $_this->_objects[$key]; + } + } + return $return; + } + +/** + * Sets the default constructor parameter for an object type + * + * @param string $type Type of object. If this parameter is omitted, defaults to "Model" + * @param array $param The parameter that will be passed to object constructors when objects + * of $type are created + * @return mixed Void if $param is being set. Otherwise, if only $type is passed, returns + * the previously-set value of $param, or null if not set. + */ + public static function config($type, $param = array()) { + $_this = ClassRegistry::getInstance(); + + if (empty($param) && is_array($type)) { + $param = $type; + $type = 'Model'; + } elseif (is_null($param)) { + unset($_this->_config[$type]); + } elseif (empty($param) && is_string($type)) { + return isset($_this->_config[$type]) ? $_this->_config[$type] : null; + } + if (isset($_this->_config[$type]['testing'])) { + $param['testing'] = true; + } + $_this->_config[$type] = $param; + } + +/** + * Checks to see if $alias is a duplicate $class Object + * + * @param string $alias + * @param string $class + * @return boolean + */ + protected function &_duplicate($alias, $class) { + $duplicate = false; + if ($this->isKeySet($alias)) { + $model = $this->getObject($alias); + if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) { + $duplicate = $model; + } + unset($model); + } + return $duplicate; + } + +/** + * Add a key name pair to the registry to map name to class in the registry. + * + * @param string $key Key to include in map + * @param string $name Key that is being mapped + * @return void + */ + public static function map($key, $name) { + $_this = ClassRegistry::getInstance(); + $key = Inflector::underscore($key); + $name = Inflector::underscore($name); + if (!isset($_this->_map[$key])) { + $_this->_map[$key] = $name; + } + } + +/** + * Get all keys from the map in the registry. + * + * @return array Keys of registry's map + */ + public static function mapKeys() { + $_this = ClassRegistry::getInstance(); + return array_keys($_this->_map); + } + +/** + * Return the name of a class in the registry. + * + * @param string $key Key to find in map + * @return string Mapped value + */ + protected function _getMap($key) { + if (isset($this->_map[$key])) { + return $this->_map[$key]; + } + } + +/** + * Flushes all objects from the ClassRegistry. + * + * @return void + */ + public static function flush() { + $_this = ClassRegistry::getInstance(); + $_this->_objects = array(); + $_this->_map = array(); + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php new file mode 100644 index 0000000..1d7410a --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Debugger.php @@ -0,0 +1,817 @@ + array( + 'trace' => '{:reference} - {:path}, line {:line}', + 'error' => "{:error} ({:code}): {:description} in [{:file}, line {:line}]" + ), + 'js' => array( + 'error' => '', + 'info' => '', + 'trace' => '
{:trace}
', + 'code' => '', + 'context' => '', + 'links' => array(), + 'escapeContext' => true, + ), + 'html' => array( + 'trace' => '
Trace 

{:trace}

', + 'context' => '
Context 

{:context}

', + 'escapeContext' => true, + ), + 'txt' => array( + 'error' => "{:error}: {:code} :: {:description} on line {:line} of {:path}\n{:info}", + 'code' => '', + 'info' => '' + ), + 'base' => array( + 'traceLine' => '{:reference} - {:path}, line {:line}', + 'trace' => "Trace:\n{:trace}\n", + 'context' => "Context:\n{:context}\n", + ), + 'log' => array(), + ); + +/** + * Holds current output data when outputFormat is false. + * + * @var string + */ + protected $_data = array(); + +/** + * Constructor. + * + */ + public function __construct() { + $docRef = ini_get('docref_root'); + + if (empty($docRef) && function_exists('ini_set')) { + ini_set('docref_root', 'http://php.net/'); + } + if (!defined('E_RECOVERABLE_ERROR')) { + define('E_RECOVERABLE_ERROR', 4096); + } + + $e = '
';
+		$e .= '{:error} ({:code}): {:description} ';
+		$e .= '[{:path}, line {:line}]';
+
+		$e .= '';
+		$e .= '
'; + $this->_templates['js']['error'] = $e; + + $t = ''; + $this->_templates['js']['info'] = $t; + + $links = array(); + $link = 'Code'; + $links['code'] = $link; + + $link = 'Context'; + $links['context'] = $link; + + $this->_templates['js']['links'] = $links; + + $this->_templates['js']['context'] = '
_templates['js']['context'] .= 'style="display: none;">{:context}
'; + + $this->_templates['js']['code'] = '
_templates['js']['code'] .= 'style="display: none;">{:code}
'; + + $e = '
{:error} ({:code}) : {:description} ';
+		$e .= '[{:path}, line {:line}]
'; + $this->_templates['html']['error'] = $e; + + $this->_templates['html']['context'] = '
Context ';
+		$this->_templates['html']['context'] .= '

{:context}

'; + } + +/** + * Returns a reference to the Debugger singleton object instance. + * + * @param string $class + * @return object + */ + public static function &getInstance($class = null) { + static $instance = array(); + if (!empty($class)) { + if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) { + $instance[0] = new $class(); + } + } + if (!$instance) { + $instance[0] = new Debugger(); + } + return $instance[0]; + } + +/** + * Recursively formats and outputs the contents of the supplied variable. + * + * + * @param mixed $var the variable to dump + * @return void + * @see Debugger::exportVar() + * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::dump + */ + public static function dump($var) { + pr(self::exportVar($var)); + } + +/** + * Creates an entry in the log file. The log entry will contain a stack trace from where it was called. + * as well as export the variable using exportVar. By default the log is written to the debug log. + * + * @param mixed $var Variable or content to log + * @param integer $level type of log to use. Defaults to LOG_DEBUG + * @return void + * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::log + */ + public static function log($var, $level = LOG_DEBUG) { + $source = self::trace(array('start' => 1)) . "\n"; + CakeLog::write($level, "\n" . $source . self::exportVar($var)); + } + +/** + * Overrides PHP's default error handling. + * + * @param integer $code Code of error + * @param string $description Error description + * @param string $file File on which error occurred + * @param integer $line Line that triggered the error + * @param array $context Context + * @return boolean true if error was handled + * @deprecated This function is superseded by Debugger::outputError() + */ + public static function showError($code, $description, $file = null, $line = null, $context = null) { + $self = Debugger::getInstance(); + + if (empty($file)) { + $file = '[internal]'; + } + if (empty($line)) { + $line = '??'; + } + $path = self::trimPath($file); + + $info = compact('code', 'description', 'file', 'line'); + if (!in_array($info, $self->errors)) { + $self->errors[] = $info; + } else { + return; + } + + switch ($code) { + case E_PARSE: + case E_ERROR: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + case E_USER_ERROR: + $error = 'Fatal Error'; + $level = LOG_ERR; + break; + case E_WARNING: + case E_USER_WARNING: + case E_COMPILE_WARNING: + case E_RECOVERABLE_ERROR: + $error = 'Warning'; + $level = LOG_WARNING; + break; + case E_NOTICE: + case E_USER_NOTICE: + $error = 'Notice'; + $level = LOG_NOTICE; + break; + case E_DEPRECATED: + case E_USER_DEPRECATED: + $error = 'Deprecated'; + $level = LOG_NOTICE; + break; + default: + return; + break; + } + + $data = compact( + 'level', 'error', 'code', 'description', 'file', 'path', 'line', 'context' + ); + echo $self->outputError($data); + + if ($error == 'Fatal Error') { + exit(); + } + return true; + } + +/** + * Outputs a stack trace based on the supplied options. + * + * ### Options + * + * - `depth` - The number of stack frames to return. Defaults to 999 + * - `format` - The format you want the return. Defaults to the currently selected format. If + * format is 'array' or 'points' the return will be an array. + * - `args` - Should arguments for functions be shown? If true, the arguments for each method call + * will be displayed. + * - `start` - The stack frame to start generating a trace from. Defaults to 0 + * + * @param array $options Format for outputting stack trace + * @return mixed Formatted stack trace + * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::trace + */ + public static function trace($options = array()) { + $self = Debugger::getInstance(); + $defaults = array( + 'depth' => 999, + 'format' => $self->_outputFormat, + 'args' => false, + 'start' => 0, + 'scope' => null, + 'exclude' => array('call_user_func_array', 'trigger_error') + ); + $options = Hash::merge($defaults, $options); + + $backtrace = debug_backtrace(); + $count = count($backtrace); + $back = array(); + + $_trace = array( + 'line' => '??', + 'file' => '[internal]', + 'class' => null, + 'function' => '[main]' + ); + + for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) { + $trace = array_merge(array('file' => '[internal]', 'line' => '??'), $backtrace[$i]); + $signature = $reference = '[main]'; + + if (isset($backtrace[$i + 1])) { + $next = array_merge($_trace, $backtrace[$i + 1]); + $signature = $reference = $next['function']; + + if (!empty($next['class'])) { + $signature = $next['class'] . '::' . $next['function']; + $reference = $signature . '('; + if ($options['args'] && isset($next['args'])) { + $args = array(); + foreach ($next['args'] as $arg) { + $args[] = Debugger::exportVar($arg); + } + $reference .= join(', ', $args); + } + $reference .= ')'; + } + } + if (in_array($signature, $options['exclude'])) { + continue; + } + if ($options['format'] == 'points' && $trace['file'] != '[internal]') { + $back[] = array('file' => $trace['file'], 'line' => $trace['line']); + } elseif ($options['format'] == 'array') { + $back[] = $trace; + } else { + if (isset($self->_templates[$options['format']]['traceLine'])) { + $tpl = $self->_templates[$options['format']]['traceLine']; + } else { + $tpl = $self->_templates['base']['traceLine']; + } + $trace['path'] = self::trimPath($trace['file']); + $trace['reference'] = $reference; + unset($trace['object'], $trace['args']); + $back[] = String::insert($tpl, $trace, array('before' => '{:', 'after' => '}')); + } + } + + if ($options['format'] == 'array' || $options['format'] == 'points') { + return $back; + } + return implode("\n", $back); + } + +/** + * Shortens file paths by replacing the application base path with 'APP', and the CakePHP core + * path with 'CORE'. + * + * @param string $path Path to shorten + * @return string Normalized path + */ + public static function trimPath($path) { + if (!defined('CAKE_CORE_INCLUDE_PATH') || !defined('APP')) { + return $path; + } + + if (strpos($path, APP) === 0) { + return str_replace(APP, 'APP' . DS, $path); + } elseif (strpos($path, CAKE_CORE_INCLUDE_PATH) === 0) { + return str_replace(CAKE_CORE_INCLUDE_PATH, 'CORE', $path); + } elseif (strpos($path, ROOT) === 0) { + return str_replace(ROOT, 'ROOT', $path); + } + + if (strpos($path, CAKE) === 0) { + return str_replace($corePath, 'CORE' . DS, $path); + } + return $path; + } + +/** + * Grabs an excerpt from a file and highlights a given line of code. + * + * Usage: + * + * `Debugger::excerpt('/path/to/file', 100, 4);` + * + * The above would return an array of 8 items. The 4th item would be the provided line, + * and would be wrapped in ``. All of the lines + * are processed with highlight_string() as well, so they have basic PHP syntax highlighting + * applied. + * + * @param string $file Absolute path to a PHP file + * @param integer $line Line number to highlight + * @param integer $context Number of lines of context to extract above and below $line + * @return array Set of lines highlighted + * @see http://php.net/highlight_string + * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::excerpt + */ + public static function excerpt($file, $line, $context = 2) { + $lines = array(); + if (!file_exists($file)) { + return array(); + } + $data = @explode("\n", file_get_contents($file)); + + if (empty($data) || !isset($data[$line])) { + return; + } + for ($i = $line - ($context + 1); $i < $line + $context; $i++) { + if (!isset($data[$i])) { + continue; + } + $string = str_replace(array("\r\n", "\n"), "", self::_highlight($data[$i])); + if ($i == $line) { + $lines[] = '' . $string . ''; + } else { + $lines[] = $string; + } + } + return $lines; + } + +/** + * Wraps the highlight_string funciton in case the server API does not + * implement the function as it is the case of the HipHop interpreter + * + * @param string $str the string to convert + * @return string + */ + protected static function _highlight($str) { + static $supportHighlight = null; + if (!$supportHighlight && function_exists('hphp_log')) { + $supportHighlight = false; + return htmlentities($str); + } + $supportHighlight = true; + return highlight_string($str, true); + } + +/** + * Converts a variable to a string for debug output. + * + * *Note:* The following keys will have their contents + * replaced with `*****`: + * + * - password + * - login + * - host + * - database + * - port + * - prefix + * - schema + * + * This is done to protect database credentials, which could be accidentally + * shown in an error message if CakePHP is deployed in development mode. + * + * @param string $var Variable to convert + * @param integer $depth The depth to output to. Defaults to 3. + * @return string Variable as a formatted string + * @link http://book.cakephp.org/2.0/en/development/debugging.html#Debugger::exportVar + */ + public static function exportVar($var, $depth = 3) { + return self::_export($var, $depth, 0); + } + +/** + * Protected export function used to keep track of indentation and recursion. + * + * @param mixed $var The variable to dump. + * @param integer $depth The remaining depth. + * @param integer $indent The current indentation level. + * @return string The dumped variable. + */ + protected static function _export($var, $depth, $indent) { + switch (self::getType($var)) { + case 'boolean': + return ($var) ? 'true' : 'false'; + break; + case 'integer': + return '(int) ' . $var; + case 'float': + return '(float) ' . $var; + break; + case 'string': + if (trim($var) == '') { + return "''"; + } + return "'" . $var . "'"; + break; + case 'array': + return self::_array($var, $depth - 1, $indent + 1); + break; + case 'resource': + return strtolower(gettype($var)); + break; + case 'null': + return 'null'; + default: + return self::_object($var, $depth - 1, $indent + 1); + break; + } + } + +/** + * Export an array type object. Filters out keys used in datasource configuration. + * + * The following keys are replaced with ***'s + * + * - password + * - login + * - host + * - database + * - port + * - prefix + * - schema + * + * @param array $var The array to export. + * @param integer $depth The current depth, used for recursion tracking. + * @param integer $indent The current indentation level. + * @return string Exported array. + */ + protected static function _array(array $var, $depth, $indent) { + $secrets = array( + 'password' => '*****', + 'login' => '*****', + 'host' => '*****', + 'database' => '*****', + 'port' => '*****', + 'prefix' => '*****', + 'schema' => '*****' + ); + $replace = array_intersect_key($secrets, $var); + $var = $replace + $var; + + $out = "array("; + $n = $break = $end = null; + if (!empty($var)) { + $n = "\n"; + $break = "\n" . str_repeat("\t", $indent); + $end = "\n" . str_repeat("\t", $indent - 1); + } + $vars = array(); + + if ($depth >= 0) { + foreach ($var as $key => $val) { + $vars[] = $break . self::exportVar($key) . + ' => ' . + self::_export($val, $depth, $indent); + } + } else { + $vars[] = $break . '[maximum depth reached]'; + } + return $out . implode(',', $vars) . $end . ')'; + } + +/** + * Handles object to string conversion. + * + * @param string $var Object to convert + * @param integer $depth The current depth, used for tracking recursion. + * @param integer $indent The current indentation level. + * @return string + * @see Debugger::exportVar() + */ + protected static function _object($var, $depth, $indent) { + $out = ''; + $props = array(); + + $className = get_class($var); + $out .= 'object(' . $className . ') {'; + + if ($depth > 0) { + $end = "\n" . str_repeat("\t", $indent - 1); + $break = "\n" . str_repeat("\t", $indent); + $objectVars = get_object_vars($var); + foreach ($objectVars as $key => $value) { + $value = self::_export($value, $depth - 1, $indent); + $props[] = "$key => " . $value; + } + $out .= $break . implode($break, $props) . $end; + } + $out .= '}'; + return $out; + } + +/** + * Get/Set the output format for Debugger error rendering. + * + * @param string $format The format you want errors to be output as. + * Leave null to get the current format. + * @return mixed Returns null when setting. Returns the current format when getting. + * @throws CakeException when choosing a format that doesn't exist. + */ + public static function outputAs($format = null) { + $self = Debugger::getInstance(); + if ($format === null) { + return $self->_outputFormat; + } + if ($format !== false && !isset($self->_templates[$format])) { + throw new CakeException(__d('cake_dev', 'Invalid Debugger output format.')); + } + $self->_outputFormat = $format; + } + +/** + * Add an output format or update a format in Debugger. + * + * `Debugger::addFormat('custom', $data);` + * + * Where $data is an array of strings that use String::insert() variable + * replacement. The template vars should be in a `{:id}` style. + * An error formatter can have the following keys: + * + * - 'error' - Used for the container for the error message. Gets the following template + * variables: `id`, `error`, `code`, `description`, `path`, `line`, `links`, `info` + * - 'info' - A combination of `code`, `context` and `trace`. Will be set with + * the contents of the other template keys. + * - 'trace' - The container for a stack trace. Gets the following template + * variables: `trace` + * - 'context' - The container element for the context variables. + * Gets the following templates: `id`, `context` + * - 'links' - An array of HTML links that are used for creating links to other resources. + * Typically this is used to create javascript links to open other sections. + * Link keys, are: `code`, `context`, `help`. See the js output format for an + * example. + * - 'traceLine' - Used for creating lines in the stacktrace. Gets the following + * template variables: `reference`, `path`, `line` + * + * Alternatively if you want to use a custom callback to do all the formatting, you can use + * the callback key, and provide a callable: + * + * `Debugger::addFormat('custom', array('callback' => array($foo, 'outputError'));` + * + * The callback can expect two parameters. The first is an array of all + * the error data. The second contains the formatted strings generated using + * the other template strings. Keys like `info`, `links`, `code`, `context` and `trace` + * will be present depending on the other templates in the format type. + * + * @param string $format Format to use, including 'js' for JavaScript-enhanced HTML, 'html' for + * straight HTML output, or 'txt' for unformatted text. + * @param array $strings Template strings, or a callback to be used for the output format. + * @return The resulting format string set. + */ + public static function addFormat($format, array $strings) { + $self = Debugger::getInstance(); + if (isset($self->_templates[$format])) { + if (isset($strings['links'])) { + $self->_templates[$format]['links'] = array_merge( + $self->_templates[$format]['links'], + $strings['links'] + ); + unset($strings['links']); + } + $self->_templates[$format] = array_merge($self->_templates[$format], $strings); + } else { + $self->_templates[$format] = $strings; + } + return $self->_templates[$format]; + } + +/** + * Switches output format, updates format strings. + * Can be used to switch the active output format: + * + * @param string $format Format to use, including 'js' for JavaScript-enhanced HTML, 'html' for + * straight HTML output, or 'txt' for unformatted text. + * @param array $strings Template strings to be used for the output format. + * @return string + * @deprecated Use Debugger::outputAs() and Debugger::addFormat(). Will be removed + * in 3.0 + */ + public function output($format = null, $strings = array()) { + $self = Debugger::getInstance(); + $data = null; + + if (is_null($format)) { + return Debugger::outputAs(); + } + + if (!empty($strings)) { + return Debugger::addFormat($format, $strings); + } + + if ($format === true && !empty($self->_data)) { + $data = $self->_data; + $self->_data = array(); + $format = false; + } + Debugger::outputAs($format); + return $data; + } + +/** + * Takes a processed array of data from an error and displays it in the chosen format. + * + * @param string $data + * @return void + */ + public function outputError($data) { + $defaults = array( + 'level' => 0, + 'error' => 0, + 'code' => 0, + 'description' => '', + 'file' => '', + 'line' => 0, + 'context' => array(), + 'start' => 2, + ); + $data += $defaults; + + $files = $this->trace(array('start' => $data['start'], 'format' => 'points')); + $code = ''; + if (isset($files[1]['file'])) { + $code = $this->excerpt($files[1]['file'], $files[1]['line'] - 1, 1); + } + $trace = $this->trace(array('start' => $data['start'], 'depth' => '20')); + $insertOpts = array('before' => '{:', 'after' => '}'); + $context = array(); + $links = array(); + $info = ''; + + foreach ((array)$data['context'] as $var => $value) { + $context[] = "\${$var} = " . $this->exportVar($value, 1); + } + + switch ($this->_outputFormat) { + case false: + $this->_data[] = compact('context', 'trace') + $data; + return; + case 'log': + $this->log(compact('context', 'trace') + $data); + return; + } + + $data['trace'] = $trace; + $data['id'] = 'cakeErr' . uniqid(); + $tpl = array_merge($this->_templates['base'], $this->_templates[$this->_outputFormat]); + + if (isset($tpl['links'])) { + foreach ($tpl['links'] as $key => $val) { + $links[$key] = String::insert($val, $data, $insertOpts); + } + } + + if (!empty($tpl['escapeContext'])) { + $context = h($context); + } + + $infoData = compact('code', 'context', 'trace'); + foreach ($infoData as $key => $value) { + if (empty($value) || !isset($tpl[$key])) { + continue; + } + if (is_array($value)) { + $value = join("\n", $value); + } + $info .= String::insert($tpl[$key], array($key => $value) + $data, $insertOpts); + } + $links = join(' ', $links); + + if (isset($tpl['callback']) && is_callable($tpl['callback'])) { + return call_user_func($tpl['callback'], $data, compact('links', 'info')); + } + echo String::insert($tpl['error'], compact('links', 'info') + $data, $insertOpts); + } + +/** + * Get the type of the given variable. Will return the classname + * for objects. + * + * @param mixed $var The variable to get the type of + * @return string The type of variable. + */ + public static function getType($var) { + if (is_object($var)) { + return get_class($var); + } + if (is_null($var)) { + return 'null'; + } + if (is_string($var)) { + return 'string'; + } + if (is_array($var)) { + return 'array'; + } + if (is_int($var)) { + return 'integer'; + } + if (is_bool($var)) { + return 'boolean'; + } + if (is_float($var)) { + return 'float'; + } + if (is_resource($var)) { + return 'resource'; + } + return 'unknown'; + } + +/** + * Verifies that the application's salt and cipher seed value has been changed from the default value. + * + * @return void + */ + public static function checkSecurityKeys() { + if (Configure::read('Security.salt') == 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi') { + trigger_error(__d('cake_dev', 'Please change the value of \'Security.salt\' in app/Config/core.php to a salt value specific to your application'), E_USER_NOTICE); + } + + if (Configure::read('Security.cipherSeed') === '76859309657453542496749683645') { + trigger_error(__d('cake_dev', 'Please change the value of \'Security.cipherSeed\' in app/Config/core.php to a numeric (digits only) seed value specific to your application'), E_USER_NOTICE); + } + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php new file mode 100644 index 0000000..6fe9399 --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/File.php @@ -0,0 +1,568 @@ +Folder = new Folder(dirname($path), $create, $mode); + if (!is_dir($path)) { + $this->name = basename($path); + } + $this->pwd(); + $create && !$this->exists() && $this->safe($path) && $this->create(); + } + +/** + * Closes the current file if it is opened + * + */ + public function __destruct() { + $this->close(); + } + +/** + * Creates the File. + * + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::create + */ + public function create() { + $dir = $this->Folder->pwd(); + if (is_dir($dir) && is_writable($dir) && !$this->exists()) { + if (touch($this->path)) { + return true; + } + } + return false; + } + +/** + * Opens the current file with a given $mode + * + * @param string $mode A valid 'fopen' mode string (r|w|a ...) + * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't + * @return boolean True on success, false on failure + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::open + */ + public function open($mode = 'r', $force = false) { + if (!$force && is_resource($this->handle)) { + return true; + } + clearstatcache(); + if ($this->exists() === false) { + if ($this->create() === false) { + return false; + } + } + + $this->handle = fopen($this->path, $mode); + if (is_resource($this->handle)) { + return true; + } + return false; + } + +/** + * Return the contents of this File as a string. + * + * @param string $bytes where to start + * @param string $mode A `fread` compatible mode. + * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't + * @return mixed string on success, false on failure + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::read + */ + public function read($bytes = false, $mode = 'rb', $force = false) { + if ($bytes === false && $this->lock === null) { + return file_get_contents($this->path); + } + if ($this->open($mode, $force) === false) { + return false; + } + if ($this->lock !== null && flock($this->handle, LOCK_SH) === false) { + return false; + } + if (is_int($bytes)) { + return fread($this->handle, $bytes); + } + + $data = ''; + while (!feof($this->handle)) { + $data .= fgets($this->handle, 4096); + } + + if ($this->lock !== null) { + flock($this->handle, LOCK_UN); + } + if ($bytes === false) { + $this->close(); + } + return trim($data); + } + +/** + * Sets or gets the offset for the currently opened file. + * + * @param integer|boolean $offset The $offset in bytes to seek. If set to false then the current offset is returned. + * @param integer $seek PHP Constant SEEK_SET | SEEK_CUR | SEEK_END determining what the $offset is relative to + * @return mixed True on success, false on failure (set mode), false on failure or integer offset on success (get mode) + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::offset + */ + public function offset($offset = false, $seek = SEEK_SET) { + if ($offset === false) { + if (is_resource($this->handle)) { + return ftell($this->handle); + } + } elseif ($this->open() === true) { + return fseek($this->handle, $offset, $seek) === 0; + } + return false; + } + +/** + * Prepares a ascii string for writing. Converts line endings to the + * correct terminator for the current platform. If windows "\r\n" will be used + * all other platforms will use "\n" + * + * @param string $data Data to prepare for writing. + * @param boolean $forceWindows + * @return string The with converted line endings. + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::prepare + */ + public static function prepare($data, $forceWindows = false) { + $lineBreak = "\n"; + if (DIRECTORY_SEPARATOR == '\\' || $forceWindows === true) { + $lineBreak = "\r\n"; + } + return strtr($data, array("\r\n" => $lineBreak, "\n" => $lineBreak, "\r" => $lineBreak)); + } + +/** + * Write given data to this File. + * + * @param string $data Data to write to this File. + * @param string $mode Mode of writing. {@link http://php.net/fwrite See fwrite()}. + * @param string $force force the file to open + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::write + */ + public function write($data, $mode = 'w', $force = false) { + $success = false; + if ($this->open($mode, $force) === true) { + if ($this->lock !== null) { + if (flock($this->handle, LOCK_EX) === false) { + return false; + } + } + + if (fwrite($this->handle, $data) !== false) { + $success = true; + } + if ($this->lock !== null) { + flock($this->handle, LOCK_UN); + } + } + return $success; + } + +/** + * Append given data string to this File. + * + * @param string $data Data to write + * @param string $force force the file to open + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::append + */ + public function append($data, $force = false) { + return $this->write($data, 'a', $force); + } + +/** + * Closes the current file if it is opened. + * + * @return boolean True if closing was successful or file was already closed, otherwise false + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::close + */ + public function close() { + if (!is_resource($this->handle)) { + return true; + } + return fclose($this->handle); + } + +/** + * Deletes the File. + * + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::delete + */ + public function delete() { + clearstatcache(); + if (is_resource($this->handle)) { + fclose($this->handle); + $this->handle = null; + } + if ($this->exists()) { + return unlink($this->path); + } + return false; + } + +/** + * Returns the File info as an array with the following keys: + * + * - dirname + * - basename + * - extension + * - filename + * - filesize + * - mime + * + * @return array File information. + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::info + */ + public function info() { + if ($this->info == null) { + $this->info = pathinfo($this->path); + } + if (!isset($this->info['filename'])) { + $this->info['filename'] = $this->name(); + } + if (!isset($this->info['filesize'])) { + $this->info['filesize'] = $this->size(); + } + if (!isset($this->info['mime'])) { + $this->info['mime'] = $this->mime(); + } + return $this->info; + } + +/** + * Returns the File extension. + * + * @return string The File extension + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::ext + */ + public function ext() { + if ($this->info == null) { + $this->info(); + } + if (isset($this->info['extension'])) { + return $this->info['extension']; + } + return false; + } + +/** + * Returns the File name without extension. + * + * @return string The File name without extension. + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::name + */ + public function name() { + if ($this->info == null) { + $this->info(); + } + if (isset($this->info['extension'])) { + return basename($this->name, '.' . $this->info['extension']); + } elseif ($this->name) { + return $this->name; + } + return false; + } + +/** + * makes filename safe for saving + * + * @param string $name The name of the file to make safe if different from $this->name + * @param string $ext The name of the extension to make safe if different from $this->ext + * @return string $ext the extension of the file + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::safe + */ + public function safe($name = null, $ext = null) { + if (!$name) { + $name = $this->name; + } + if (!$ext) { + $ext = $this->ext(); + } + return preg_replace("/(?:[^\w\.-]+)/", "_", basename($name, $ext)); + } + +/** + * Get md5 Checksum of file with previous check of Filesize + * + * @param integer|boolean $maxsize in MB or true to force + * @return string md5 Checksum {@link http://php.net/md5_file See md5_file()} + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::md5 + */ + public function md5($maxsize = 5) { + if ($maxsize === true) { + return md5_file($this->path); + } + + $size = $this->size(); + if ($size && $size < ($maxsize * 1024) * 1024) { + return md5_file($this->path); + } + + return false; + } + +/** + * Returns the full path of the File. + * + * @return string Full path to file + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::pwd + */ + public function pwd() { + if (is_null($this->path)) { + $this->path = $this->Folder->slashTerm($this->Folder->pwd()) . $this->name; + } + return $this->path; + } + +/** + * Returns true if the File exists. + * + * @return boolean true if it exists, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::exists + */ + public function exists() { + return (file_exists($this->path) && is_file($this->path)); + } + +/** + * Returns the "chmod" (permissions) of the File. + * + * @return string Permissions for the file + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::perms + */ + public function perms() { + if ($this->exists()) { + return substr(sprintf('%o', fileperms($this->path)), -4); + } + return false; + } + +/** + * Returns the Filesize + * + * @return integer size of the file in bytes, or false in case of an error + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::size + */ + public function size() { + if ($this->exists()) { + return filesize($this->path); + } + return false; + } + +/** + * Returns true if the File is writable. + * + * @return boolean true if its writable, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::writable + */ + public function writable() { + return is_writable($this->path); + } + +/** + * Returns true if the File is executable. + * + * @return boolean true if its executable, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::executable + */ + public function executable() { + return is_executable($this->path); + } + +/** + * Returns true if the File is readable. + * + * @return boolean true if file is readable, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::readable + */ + public function readable() { + return is_readable($this->path); + } + +/** + * Returns the File's owner. + * + * @return integer the Fileowner + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::owner + */ + public function owner() { + if ($this->exists()) { + return fileowner($this->path); + } + return false; + } + +/** + * Returns the File's group. + * + * @return integer the Filegroup + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::group + */ + public function group() { + if ($this->exists()) { + return filegroup($this->path); + } + return false; + } + +/** + * Returns last access time. + * + * @return integer timestamp Timestamp of last access time + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::lastAccess + */ + public function lastAccess() { + if ($this->exists()) { + return fileatime($this->path); + } + return false; + } + +/** + * Returns last modified time. + * + * @return integer timestamp Timestamp of last modification + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::lastChange + */ + public function lastChange() { + if ($this->exists()) { + return filemtime($this->path); + } + return false; + } + +/** + * Returns the current folder. + * + * @return Folder Current folder + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::Folder + */ + public function &folder() { + return $this->Folder; + } + +/** + * Copy the File to $dest + * + * @param string $dest destination for the copy + * @param boolean $overwrite Overwrite $dest if exists + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#File::copy + */ + public function copy($dest, $overwrite = true) { + if (!$this->exists() || is_file($dest) && !$overwrite) { + return false; + } + return copy($this->path, $dest); + } + +/** + * Get the mime type of the file. Uses the finfo extension if + * its available, otherwise falls back to mime_content_type + * + * @return false|string The mimetype of the file, or false if reading fails. + */ + public function mime() { + if (!$this->exists()) { + return false; + } + if (function_exists('finfo_open')) { + $finfo = finfo_open(FILEINFO_MIME); + list($type, $charset) = explode(';', finfo_file($finfo, $this->pwd())); + return $type; + } elseif (function_exists('mime_content_type')) { + return mime_content_type($this->pwd()); + } + return false; + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php new file mode 100644 index 0000000..08895bf --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Folder.php @@ -0,0 +1,780 @@ +mode = $mode; + } + + if (!file_exists($path) && $create === true) { + $this->create($path, $this->mode); + } + if (!Folder::isAbsolute($path)) { + $path = realpath($path); + } + if (!empty($path)) { + $this->cd($path); + } + } + +/** + * Return current path. + * + * @return string Current path + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::pwd + */ + public function pwd() { + return $this->path; + } + +/** + * Change directory to $path. + * + * @param string $path Path to the directory to change to + * @return string The new path. Returns false on failure + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::cd + */ + public function cd($path) { + $path = $this->realpath($path); + if (is_dir($path)) { + return $this->path = $path; + } + return false; + } + +/** + * Returns an array of the contents of the current directory. + * The returned array holds two arrays: One of directories and one of files. + * + * @param boolean $sort Whether you want the results sorted, set this and the sort property + * to false to get unsorted results. + * @param array|boolean $exceptions Either an array or boolean true will not grab dot files + * @param boolean $fullPath True returns the full path + * @return mixed Contents of current directory as an array, an empty array on failure + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::read + */ + public function read($sort = true, $exceptions = false, $fullPath = false) { + $dirs = $files = array(); + + if (!$this->pwd()) { + return array($dirs, $files); + } + if (is_array($exceptions)) { + $exceptions = array_flip($exceptions); + } + $skipHidden = isset($exceptions['.']) || $exceptions === true; + + try { + $iterator = new DirectoryIterator($this->path); + } catch (Exception $e) { + return array($dirs, $files); + } + + foreach ($iterator as $item) { + if ($item->isDot()) { + continue; + } + $name = $item->getFileName(); + if ($skipHidden && $name[0] === '.' || isset($exceptions[$name])) { + continue; + } + if ($fullPath) { + $name = $item->getPathName(); + } + if ($item->isDir()) { + $dirs[] = $name; + } else { + $files[] = $name; + } + } + if ($sort || $this->sort) { + sort($dirs); + sort($files); + } + return array($dirs, $files); + } + +/** + * Returns an array of all matching files in current directory. + * + * @param string $regexpPattern Preg_match pattern (Defaults to: .*) + * @param boolean $sort Whether results should be sorted. + * @return array Files that match given pattern + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::find + */ + public function find($regexpPattern = '.*', $sort = false) { + list($dirs, $files) = $this->read($sort); + return array_values(preg_grep('/^' . $regexpPattern . '$/i', $files)); + } + +/** + * Returns an array of all matching files in and below current directory. + * + * @param string $pattern Preg_match pattern (Defaults to: .*) + * @param boolean $sort Whether results should be sorted. + * @return array Files matching $pattern + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::findRecursive + */ + public function findRecursive($pattern = '.*', $sort = false) { + if (!$this->pwd()) { + return array(); + } + $startsOn = $this->path; + $out = $this->_findRecursive($pattern, $sort); + $this->cd($startsOn); + return $out; + } + +/** + * Private helper function for findRecursive. + * + * @param string $pattern Pattern to match against + * @param boolean $sort Whether results should be sorted. + * @return array Files matching pattern + */ + protected function _findRecursive($pattern, $sort = false) { + list($dirs, $files) = $this->read($sort); + $found = array(); + + foreach ($files as $file) { + if (preg_match('/^' . $pattern . '$/i', $file)) { + $found[] = Folder::addPathElement($this->path, $file); + } + } + $start = $this->path; + + foreach ($dirs as $dir) { + $this->cd(Folder::addPathElement($start, $dir)); + $found = array_merge($found, $this->findRecursive($pattern, $sort)); + } + return $found; + } + +/** + * Returns true if given $path is a Windows path. + * + * @param string $path Path to check + * @return boolean true if windows path, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isWindowsPath + */ + public static function isWindowsPath($path) { + return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\'); + } + +/** + * Returns true if given $path is an absolute path. + * + * @param string $path Path to check + * @return boolean true if path is absolute. + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isAbsolute + */ + public static function isAbsolute($path) { + return !empty($path) && ($path[0] === '/' || preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\'); + } + +/** + * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.) + * + * @param string $path Path to check + * @return string Set of slashes ("\\" or "/") + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::normalizePath + */ + public static function normalizePath($path) { + return Folder::correctSlashFor($path); + } + +/** + * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.) + * + * @param string $path Path to check + * @return string Set of slashes ("\\" or "/") + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::correctSlashFor + */ + public static function correctSlashFor($path) { + return (Folder::isWindowsPath($path)) ? '\\' : '/'; + } + +/** + * Returns $path with added terminating slash (corrected for Windows or other OS). + * + * @param string $path Path to check + * @return string Path with ending slash + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::slashTerm + */ + public static function slashTerm($path) { + if (Folder::isSlashTerm($path)) { + return $path; + } + return $path . Folder::correctSlashFor($path); + } + +/** + * Returns $path with $element added, with correct slash in-between. + * + * @param string $path Path + * @param string $element Element to and at end of path + * @return string Combined path + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::addPathElement + */ + public static function addPathElement($path, $element) { + return rtrim($path, DS) . DS . $element; + } + +/** + * Returns true if the File is in a given CakePath. + * + * @param string $path The path to check. + * @return boolean + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::inCakePath + */ + public function inCakePath($path = '') { + $dir = substr(Folder::slashTerm(ROOT), 0, -1); + $newdir = $dir . $path; + + return $this->inPath($newdir); + } + +/** + * Returns true if the File is in given path. + * + * @param string $path The path to check that the current pwd() resides with in. + * @param boolean $reverse Reverse the search, check that pwd() resides within $path. + * @return boolean + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::inPath + */ + public function inPath($path = '', $reverse = false) { + $dir = Folder::slashTerm($path); + $current = Folder::slashTerm($this->pwd()); + + if (!$reverse) { + $return = preg_match('/^(.*)' . preg_quote($dir, '/') . '(.*)/', $current); + } else { + $return = preg_match('/^(.*)' . preg_quote($current, '/') . '(.*)/', $dir); + } + return (bool)$return; + } + +/** + * Change the mode on a directory structure recursively. This includes changing the mode on files as well. + * + * @param string $path The path to chmod + * @param integer $mode octal value 0755 + * @param boolean $recursive chmod recursively, set to false to only change the current directory. + * @param array $exceptions array of files, directories to skip + * @return boolean Returns TRUE on success, FALSE on failure + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::chmod + */ + public function chmod($path, $mode = false, $recursive = true, $exceptions = array()) { + if (!$mode) { + $mode = $this->mode; + } + + if ($recursive === false && is_dir($path)) { + if (@chmod($path, intval($mode, 8))) { + $this->_messages[] = __d('cake_dev', '%s changed to %s', $path, $mode); + return true; + } + + $this->_errors[] = __d('cake_dev', '%s NOT changed to %s', $path, $mode); + return false; + } + + if (is_dir($path)) { + $paths = $this->tree($path); + + foreach ($paths as $type) { + foreach ($type as $key => $fullpath) { + $check = explode(DS, $fullpath); + $count = count($check); + + if (in_array($check[$count - 1], $exceptions)) { + continue; + } + + if (@chmod($fullpath, intval($mode, 8))) { + $this->_messages[] = __d('cake_dev', '%s changed to %s', $fullpath, $mode); + } else { + $this->_errors[] = __d('cake_dev', '%s NOT changed to %s', $fullpath, $mode); + } + } + } + + if (empty($this->_errors)) { + return true; + } + } + return false; + } + +/** + * Returns an array of nested directories and files in each directory + * + * @param string $path the directory path to build the tree from + * @param array|boolean $exceptions Either an array of files/folder to exclude + * or boolean true to not grab dot files/folders + * @param string $type either 'file' or 'dir'. null returns both files and directories + * @return mixed array of nested directories and files in each directory + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::tree + */ + public function tree($path = null, $exceptions = false, $type = null) { + if ($path == null) { + $path = $this->path; + } + $files = array(); + $directories = array($path); + + if (is_array($exceptions)) { + $exceptions = array_flip($exceptions); + } + $skipHidden = false; + if ($exceptions === true) { + $skipHidden = true; + } elseif (isset($exceptions['.'])) { + $skipHidden = true; + unset($exceptions['.']); + } + + try { + $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_PATHNAME | RecursiveDirectoryIterator::CURRENT_AS_SELF); + $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); + } catch (Exception $e) { + if ($type === null) { + return array(array(), array()); + } + return array(); + } + + foreach ($iterator as $itemPath => $fsIterator) { + if ($skipHidden) { + $subPathName = $fsIterator->getSubPathname(); + if ($subPathName{0} == '.' || strpos($subPathName, DS . '.') !== false) { + continue; + } + } + $item = $fsIterator->current(); + if (!empty($exceptions) && isset($exceptions[$item->getFilename()])) { + continue; + } + + if ($item->isFile()) { + $files[] = $itemPath; + } elseif ($item->isDir() && !$item->isDot()) { + $directories[] = $itemPath; + } + } + if ($type === null) { + return array($directories, $files); + } + if ($type === 'dir') { + return $directories; + } + return $files; + } + +/** + * Create a directory structure recursively. Can be used to create + * deep path structures like `/foo/bar/baz/shoe/horn` + * + * @param string $pathname The directory structure to create + * @param integer $mode octal value 0755 + * @return boolean Returns TRUE on success, FALSE on failure + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::create + */ + public function create($pathname, $mode = false) { + if (is_dir($pathname) || empty($pathname)) { + return true; + } + + if (!$mode) { + $mode = $this->mode; + } + + if (is_file($pathname)) { + $this->_errors[] = __d('cake_dev', '%s is a file', $pathname); + return false; + } + $pathname = rtrim($pathname, DS); + $nextPathname = substr($pathname, 0, strrpos($pathname, DS)); + + if ($this->create($nextPathname, $mode)) { + if (!file_exists($pathname)) { + $old = umask(0); + if (mkdir($pathname, $mode)) { + umask($old); + $this->_messages[] = __d('cake_dev', '%s created', $pathname); + return true; + } else { + umask($old); + $this->_errors[] = __d('cake_dev', '%s NOT created', $pathname); + return false; + } + } + } + return false; + } + +/** + * Returns the size in bytes of this Folder and its contents. + * + * @return integer size in bytes of current folder + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::dirsize + */ + public function dirsize() { + $size = 0; + $directory = Folder::slashTerm($this->path); + $stack = array($directory); + $count = count($stack); + for ($i = 0, $j = $count; $i < $j; ++$i) { + if (is_file($stack[$i])) { + $size += filesize($stack[$i]); + } elseif (is_dir($stack[$i])) { + $dir = dir($stack[$i]); + if ($dir) { + while (false !== ($entry = $dir->read())) { + if ($entry === '.' || $entry === '..') { + continue; + } + $add = $stack[$i] . $entry; + + if (is_dir($stack[$i] . $entry)) { + $add = Folder::slashTerm($add); + } + $stack[] = $add; + } + $dir->close(); + } + } + $j = count($stack); + } + return $size; + } + +/** + * Recursively Remove directories if the system allows. + * + * @param string $path Path of directory to delete + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::delete + */ + public function delete($path = null) { + if (!$path) { + $path = $this->pwd(); + } + if (!$path) { + return null; + } + $path = Folder::slashTerm($path); + if (is_dir($path)) { + try { + $directory = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::CURRENT_AS_SELF); + $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::CHILD_FIRST); + } catch (Exception $e) { + return false; + } + + foreach ($iterator as $item) { + $filePath = $item->getPathname(); + if ($item->isFile() || $item->isLink()) { + if (@unlink($filePath)) { + $this->_messages[] = __d('cake_dev', '%s removed', $filePath); + } else { + $this->_errors[] = __d('cake_dev', '%s NOT removed', $filePath); + } + } elseif ($item->isDir() && !$item->isDot()) { + if (@rmdir($filePath)) { + $this->_messages[] = __d('cake_dev', '%s removed', $filePath); + } else { + $this->_errors[] = __d('cake_dev', '%s NOT removed', $filePath); + return false; + } + } + } + + $path = rtrim($path, DS); + if (@rmdir($path)) { + $this->_messages[] = __d('cake_dev', '%s removed', $path); + } else { + $this->_errors[] = __d('cake_dev', '%s NOT removed', $path); + return false; + } + } + return true; + } + +/** + * Recursive directory copy. + * + * ### Options + * + * - `to` The directory to copy to. + * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd(). + * - `mode` The mode to copy the files/directories with. + * - `skip` Files/directories to skip. + * + * @param array|string $options Either an array of options (see above) or a string of the destination directory. + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::copy + */ + public function copy($options = array()) { + if (!$this->pwd()) { + return false; + } + $to = null; + if (is_string($options)) { + $to = $options; + $options = array(); + } + $options = array_merge(array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array()), $options); + + $fromDir = $options['from']; + $toDir = $options['to']; + $mode = $options['mode']; + + if (!$this->cd($fromDir)) { + $this->_errors[] = __d('cake_dev', '%s not found', $fromDir); + return false; + } + + if (!is_dir($toDir)) { + $this->create($toDir, $mode); + } + + if (!is_writable($toDir)) { + $this->_errors[] = __d('cake_dev', '%s not writable', $toDir); + return false; + } + + $exceptions = array_merge(array('.', '..', '.svn'), $options['skip']); + if ($handle = @opendir($fromDir)) { + while (false !== ($item = readdir($handle))) { + if (!in_array($item, $exceptions)) { + $from = Folder::addPathElement($fromDir, $item); + $to = Folder::addPathElement($toDir, $item); + if (is_file($from)) { + if (copy($from, $to)) { + chmod($to, intval($mode, 8)); + touch($to, filemtime($from)); + $this->_messages[] = __d('cake_dev', '%s copied to %s', $from, $to); + } else { + $this->_errors[] = __d('cake_dev', '%s NOT copied to %s', $from, $to); + } + } + + if (is_dir($from) && !file_exists($to)) { + $old = umask(0); + if (mkdir($to, $mode)) { + umask($old); + $old = umask(0); + chmod($to, $mode); + umask($old); + $this->_messages[] = __d('cake_dev', '%s created', $to); + $options = array_merge($options, array('to' => $to, 'from' => $from)); + $this->copy($options); + } else { + $this->_errors[] = __d('cake_dev', '%s not created', $to); + } + } + } + } + closedir($handle); + } else { + return false; + } + + if (!empty($this->_errors)) { + return false; + } + return true; + } + +/** + * Recursive directory move. + * + * ### Options + * + * - `to` The directory to copy to. + * - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd(). + * - `chmod` The mode to copy the files/directories with. + * - `skip` Files/directories to skip. + * + * @param array $options (to, from, chmod, skip) + * @return boolean Success + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::move + */ + public function move($options) { + $to = null; + if (is_string($options)) { + $to = $options; + $options = (array)$options; + } + $options = array_merge( + array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array()), + $options + ); + + if ($this->copy($options)) { + if ($this->delete($options['from'])) { + return (bool)$this->cd($options['to']); + } + } + return false; + } + +/** + * get messages from latest method + * + * @return array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::messages + */ + public function messages() { + return $this->_messages; + } + +/** + * get error from latest method + * + * @return array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::errors + */ + public function errors() { + return $this->_errors; + } + +/** + * Get the real path (taking ".." and such into account) + * + * @param string $path Path to resolve + * @return string The resolved path + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::realpath + */ + public function realpath($path) { + $path = str_replace('/', DS, trim($path)); + if (strpos($path, '..') === false) { + if (!Folder::isAbsolute($path)) { + $path = Folder::addPathElement($this->path, $path); + } + return $path; + } + $parts = explode(DS, $path); + $newparts = array(); + $newpath = ''; + if ($path[0] === DS) { + $newpath = DS; + } + + while (($part = array_shift($parts)) !== null) { + if ($part === '.' || $part === '') { + continue; + } + if ($part === '..') { + if (!empty($newparts)) { + array_pop($newparts); + continue; + } else { + return false; + } + } + $newparts[] = $part; + } + $newpath .= implode(DS, $newparts); + + return Folder::slashTerm($newpath); + } + +/** + * Returns true if given $path ends in a slash (i.e. is slash-terminated). + * + * @param string $path Path to check + * @return boolean true if path ends with slash, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/file-folder.html#Folder::isSlashTerm + */ + public static function isSlashTerm($path) { + $lastChar = $path[strlen($path) - 1]; + return $lastChar === '/' || $lastChar === '\\'; + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php new file mode 100644 index 0000000..9514ccc --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Hash.php @@ -0,0 +1,974 @@ +`, `<`, `>=`, `<=` Value comparison. + * - `=/.../` Regular expression pattern match. + * + * Given a set of User array data, from a `$User->find('all')` call: + * + * - `1.User.name` Get the name of the user at index 1. + * - `{n}.User.name` Get the name of every user in the set of users. + * - `{n}.User[id]` Get the name of every user with an id key. + * - `{n}.User[id>=2]` Get the name of every user with an id key greater than or equal to 2. + * - `{n}.User[username=/^paul/]` Get User elements with username matching `^paul`. + * + * @param array $data The data to extract from. + * @param string $path The path to extract. + * @return array An array of the extracted values. Returns an empty array + * if there are no matches. + */ + public static function extract(array $data, $path) { + if (empty($path)) { + return $data; + } + + // Simple paths. + if (!preg_match('/[{\[]/', $path)) { + return (array)self::get($data, $path); + } + + if (strpos('[', $path) === false) { + $tokens = explode('.', $path); + } else { + $tokens = String::tokenize($path, '.', '[', ']'); + } + + $_key = '__set_item__'; + + $context = array($_key => array($data)); + + foreach ($tokens as $token) { + $next = array(); + + $conditions = false; + $position = strpos($token, '['); + if ($position !== false) { + $conditions = substr($token, $position); + $token = substr($token, 0, $position); + } + + foreach ($context[$_key] as $item) { + foreach ($item as $k => $v) { + if (self::_matchToken($k, $token)) { + $next[] = $v; + } + } + } + + // Filter for attributes. + if ($conditions) { + $filter = array(); + foreach ($next as $item) { + if (self::_matches($item, $conditions)) { + $filter[] = $item; + } + } + $next = $filter; + } + $context = array($_key => $next); + + } + return $context[$_key]; + } + +/** + * Check a key against a token. + * + * @param string $key The key in the array being searched. + * @param string $token The token being matched. + * @return boolean + */ + protected static function _matchToken($key, $token) { + if ($token === '{n}') { + return is_numeric($key); + } + if ($token === '{s}') { + return is_string($key); + } + if (is_numeric($token)) { + return ($key == $token); + } + return ($key === $token); + } + +/** + * Checks whether or not $data matches the attribute patterns + * + * @param array $data Array of data to match. + * @param string $selector The patterns to match. + * @return boolean Fitness of expression. + */ + protected static function _matches(array $data, $selector) { + preg_match_all( + '/(\[ (?[^=>[><]) \s* (?[^\]]+) )? \])/x', + $selector, + $conditions, + PREG_SET_ORDER + ); + + foreach ($conditions as $cond) { + $attr = $cond['attr']; + $op = isset($cond['op']) ? $cond['op'] : null; + $val = isset($cond['val']) ? $cond['val'] : null; + + // Presence test. + if (empty($op) && empty($val) && !isset($data[$attr])) { + return false; + } + + // Empty attribute = fail. + if (!(isset($data[$attr]) || array_key_exists($attr, $data))) { + return false; + } + + $prop = isset($data[$attr]) ? $data[$attr] : null; + + // Pattern matches and other operators. + if ($op === '=' && $val && $val[0] === '/') { + if (!preg_match($val, $prop)) { + return false; + } + } elseif ( + ($op === '=' && $prop != $val) || + ($op === '!=' && $prop == $val) || + ($op === '>' && $prop <= $val) || + ($op === '<' && $prop >= $val) || + ($op === '>=' && $prop < $val) || + ($op === '<=' && $prop > $val) + ) { + return false; + } + + } + return true; + } + +/** + * Insert $values into an array with the given $path. You can use + * `{n}` and `{s}` elements to insert $data multiple times. + * + * @param array $data The data to insert into. + * @param string $path The path to insert at. + * @param array $values The values to insert. + * @return array The data with $values inserted. + */ + public static function insert(array $data, $path, $values = null) { + $tokens = explode('.', $path); + if (strpos($path, '{') === false) { + return self::_simpleOp('insert', $data, $tokens, $values); + } + + $token = array_shift($tokens); + $nextPath = implode('.', $tokens); + foreach ($data as $k => $v) { + if (self::_matchToken($k, $token)) { + $data[$k] = self::insert($v, $nextPath, $values); + } + } + return $data; + } + +/** + * Perform a simple insert/remove operation. + * + * @param string $op The operation to do. + * @param array $data The data to operate on. + * @param array $path The path to work on. + * @param mixed $values The values to insert when doing inserts. + * @return array $data. + */ + protected static function _simpleOp($op, $data, $path, $values = null) { + $_list =& $data; + + $count = count($path); + $last = $count - 1; + foreach ($path as $i => $key) { + if (is_numeric($key) && intval($key) > 0 || $key === '0') { + $key = intval($key); + } + if ($op === 'insert') { + if ($i === $last) { + $_list[$key] = $values; + return $data; + } + if (!isset($_list[$key])) { + $_list[$key] = array(); + } + $_list =& $_list[$key]; + if (!is_array($_list)) { + $_list = array(); + } + } elseif ($op === 'remove') { + if ($i === $last) { + unset($_list[$key]); + return $data; + } + if (!isset($_list[$key])) { + return $data; + } + $_list =& $_list[$key]; + } + } + } + +/** + * Remove data matching $path from the $data array. + * You can use `{n}` and `{s}` to remove multiple elements + * from $data. + * + * @param array $data The data to operate on + * @param string $path A path expression to use to remove. + * @return array The modified array. + */ + public static function remove(array $data, $path) { + $tokens = explode('.', $path); + if (strpos($path, '{') === false) { + return self::_simpleOp('remove', $data, $tokens); + } + + $token = array_shift($tokens); + $nextPath = implode('.', $tokens); + foreach ($data as $k => $v) { + $match = self::_matchToken($k, $token); + if ($match && is_array($v)) { + $data[$k] = self::remove($v, $nextPath); + } elseif ($match) { + unset($data[$k]); + } + } + return $data; + } + +/** + * Creates an associative array using `$keyPath` as the path to build its keys, and optionally + * `$valuePath` as path to get the values. If `$valuePath` is not specified, all values will be initialized + * to null (useful for Hash::merge). You can optionally group the values by what is obtained when + * following the path specified in `$groupPath`. + * + * @param array $data Array from where to extract keys and values + * @param string $keyPath A dot-separated string. + * @param string $valuePath A dot-separated string. + * @param string $groupPath A dot-separated string. + * @return array Combined array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::combine + */ + public static function combine(array $data, $keyPath, $valuePath = null, $groupPath = null) { + if (empty($data)) { + return array(); + } + + if (is_array($keyPath)) { + $format = array_shift($keyPath); + $keys = self::format($data, $keyPath, $format); + } else { + $keys = self::extract($data, $keyPath); + } + if (empty($keys)) { + return array(); + } + + if (!empty($valuePath) && is_array($valuePath)) { + $format = array_shift($valuePath); + $vals = self::format($data, $valuePath, $format); + } elseif (!empty($valuePath)) { + $vals = self::extract($data, $valuePath); + } + + $count = count($keys); + for ($i = 0; $i < $count; $i++) { + $vals[$i] = isset($vals[$i]) ? $vals[$i] : null; + } + + if ($groupPath !== null) { + $group = self::extract($data, $groupPath); + if (!empty($group)) { + $c = count($keys); + for ($i = 0; $i < $c; $i++) { + if (!isset($group[$i])) { + $group[$i] = 0; + } + if (!isset($out[$group[$i]])) { + $out[$group[$i]] = array(); + } + $out[$group[$i]][$keys[$i]] = $vals[$i]; + } + return $out; + } + } + if (empty($vals)) { + return array(); + } + return array_combine($keys, $vals); + } + +/** + * Returns a formated series of values extracted from `$data`, using + * `$format` as the format and `$paths` as the values to extract. + * + * Usage: + * + * {{{ + * $result = Hash::format($users, array('{n}.User.id', '{n}.User.name'), '%s : %s'); + * }}} + * + * The `$format` string can use any format options that `vsprintf()` and `sprintf()` do. + * + * @param array $data Source array from which to extract the data + * @param string $paths An array containing one or more Hash::extract()-style key paths + * @param string $format Format string into which values will be inserted, see sprintf() + * @return array An array of strings extracted from `$path` and formatted with `$format` + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::format + * @see sprintf() + * @see Hash::extract() + */ + public static function format(array $data, array $paths, $format) { + $extracted = array(); + $count = count($paths); + + if (!$count) { + return; + } + + for ($i = 0; $i < $count; $i++) { + $extracted[] = self::extract($data, $paths[$i]); + } + $out = array(); + $data = $extracted; + $count = count($data[0]); + + $countTwo = count($data); + for ($j = 0; $j < $count; $j++) { + $args = array(); + for ($i = 0; $i < $countTwo; $i++) { + if (array_key_exists($j, $data[$i])) { + $args[] = $data[$i][$j]; + } + } + $out[] = vsprintf($format, $args); + } + return $out; + } + +/** + * Determines if one array contains the exact keys and values of another. + * + * @param array $data The data to search through. + * @param array $needle The values to file in $data + * @return boolean true if $data contains $needle, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::contains + */ + public static function contains(array $data, array $needle) { + if (empty($data) || empty($needle)) { + return false; + } + $stack = array(); + + $i = 1; + while (!empty($needle)) { + $key = key($needle); + $val = $needle[$key]; + unset($needle[$key]); + + if (isset($data[$key]) && is_array($val)) { + $next = $data[$key]; + unset($data[$key]); + + if (!empty($val)) { + $stack[] = array($val, $next); + } + } elseif (!isset($data[$key]) || $data[$key] != $val) { + return false; + } + + if (empty($needle) && !empty($stack)) { + list($needle, $data) = array_pop($stack); + } + } + return true; + } + +/** + * Test whether or not a given path exists in $data. + * This method uses the same path syntax as Hash::extract() + * + * Checking for paths that could target more than one element will + * make sure that at least one matching element exists. + * + * @param array $data The data to check. + * @param string $path The path to check for. + * @return boolean Existence of path. + * @see Hash::extract() + */ + public static function check(array $data, $path) { + $results = self::extract($data, $path); + if (!is_array($results)) { + return false; + } + return count($results) > 0; + } + +/** + * Recursively filters a data set. + * + * @param array $data Either an array to filter, or value when in callback + * @param callable $callback A function to filter the data with. Defaults to + * `self::_filter()` Which strips out all non-zero empty values. + * @return array Filtered array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::filter + */ + public static function filter(array $data, $callback = array('self', '_filter')) { + foreach ($data as $k => $v) { + if (is_array($v)) { + $data[$k] = self::filter($v, $callback); + } + } + return array_filter($data, $callback); + } + +/** + * Callback function for filtering. + * + * @param array $var Array to filter. + * @return boolean + */ + protected static function _filter($var) { + if ($var === 0 || $var === '0' || !empty($var)) { + return true; + } + return false; + } + +/** + * Collapses a multi-dimensional array into a single dimension, using a delimited array path for + * each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes + * array('0.Foo.Bar' => 'Far').) + * + * @param array $data Array to flatten + * @param string $separator String used to separate array key elements in a path, defaults to '.' + * @return array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::flatten + */ + public static function flatten(array $data, $separator = '.') { + $result = array(); + $stack = array(); + $path = null; + + reset($data); + while (!empty($data)) { + $key = key($data); + $element = $data[$key]; + unset($data[$key]); + + if (is_array($element)) { + if (!empty($data)) { + $stack[] = array($data, $path); + } + $data = $element; + $path .= $key . $separator; + } else { + $result[$path . $key] = $element; + } + + if (empty($data) && !empty($stack)) { + list($data, $path) = array_pop($stack); + } + } + return $result; + } + +/** + * Expand/unflattens an string to an array + * + * For example, unflattens an array that was collapsed with `Hash::flatten()` + * into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes + * `array(array('Foo' => array('Bar' => 'Far')))`. + * + * @param array $data Flattened array + * @param string $separator The delimiter used + * @return array + */ + public static function expand($data, $separator = '.') { + $result = array(); + foreach ($data as $flat => $value) { + $keys = explode($separator, $flat); + $keys = array_reverse($keys); + $child = array( + $keys[0] => $value + ); + array_shift($keys); + foreach ($keys as $k) { + $child = array( + $k => $child + ); + } + $result = self::merge($result, $child); + } + return $result; + } + +/** + * This function can be thought of as a hybrid between PHP's `array_merge` and `array_merge_recursive`. + * + * The difference between this method and the built-in ones, is that if an array key contains another array, then + * Hash::merge() will behave in a recursive fashion (unlike `array_merge`). But it will not act recursively for + * keys that contain scalar values (unlike `array_merge_recursive`). + * + * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays. + * + * @param array $data Array to be merged + * @param mixed $merge Array to merge with. The argument and all trailing arguments will be array cast when merged + * @return array Merged array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::merge + */ + public static function merge(array $data, $merge) { + $args = func_get_args(); + $return = current($args); + + while (($arg = next($args)) !== false) { + foreach ((array)$arg as $key => $val) { + if (!empty($return[$key]) && is_array($return[$key]) && is_array($val)) { + $return[$key] = self::merge($return[$key], $val); + } elseif (is_int($key)) { + $return[] = $val; + } else { + $return[$key] = $val; + } + } + } + return $return; + } + +/** + * Checks to see if all the values in the array are numeric + * + * @param array $array The array to check. + * @return boolean true if values are numeric, false otherwise + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::numeric + */ + public static function numeric(array $data) { + if (empty($data)) { + return false; + } + $values = array_values($data); + $str = implode('', $values); + return (bool)ctype_digit($str); + } + +/** + * Counts the dimensions of an array. + * Only considers the dimension of the first element in the array. + * + * If you have an un-even or hetrogenous array, consider using Hash::maxDimensions() + * to get the dimensions of the array. + * + * @param array $array Array to count dimensions on + * @return integer The number of dimensions in $data + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::dimensions + */ + public static function dimensions(array $data) { + if (empty($data)) { + return 0; + } + reset($data); + $depth = 1; + while ($elem = array_shift($data)) { + if (is_array($elem)) { + $depth += 1; + $data =& $elem; + } else { + break; + } + } + return $depth; + } + +/** + * Counts the dimensions of *all* array elements. Useful for finding the maximum + * number of dimensions in a mixed array. + * + * @param array $data Array to count dimensions on + * @return integer The maximum number of dimensions in $data + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::maxDimensions + */ + public static function maxDimensions(array $data) { + $depth = array(); + if (is_array($data) && reset($data) !== false) { + foreach ($data as $value) { + $depth[] = self::dimensions((array)$value) + 1; + } + } + return max($depth); + } + +/** + * Map a callback across all elements in a set. + * Can be provided a path to only modify slices of the set. + * + * @param array $data The data to map over, and extract data out of. + * @param string $path The path to extract for mapping over. + * @param callable $function The function to call on each extracted value. + * @return array An array of the modified values. + */ + public static function map(array $data, $path, $function) { + $values = (array)self::extract($data, $path); + return array_map($function, $values); + } + +/** + * Reduce a set of extracted values using `$function`. + * + * @param array $data The data to reduce. + * @param string $path The path to extract from $data. + * @return mixed The reduced value. + */ + public static function reduce(array $data, $path, $function) { + $values = (array)self::extract($data, $path); + return array_reduce($values, $function); + } + +/** + * Apply a callback to a set of extracted values using `$function`. + * The function will get the extracted values as the first argument. + * + * @param array $data The data to reduce. + * @param string $path The path to extract from $data. + * @return mixed The results of the applied method. + */ + public static function apply(array $data, $path, $function) { + $values = (array)self::extract($data, $path); + return call_user_func($function, $values); + } + +/** + * Sorts an array by any value, determined by a Set-compatible path + * + * ### Sort directions + * + * - `asc` Sort ascending. + * - `desc` Sort descending. + * + * ## Sort types + * + * - `numeric` Sort by numeric value. + * - `regular` Sort by numeric value. + * - `string` Sort by numeric value. + * - `natural` Sort by natural order. Requires PHP 5.4 or greater. + * + * @param array $data An array of data to sort + * @param string $path A Set-compatible path to the array value + * @param string $dir See directions above. + * @param string $type See direction types above. Defaults to 'regular'. + * @return array Sorted array of data + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::sort + */ + public static function sort(array $data, $path, $dir, $type = 'regular') { + $originalKeys = array_keys($data); + $numeric = is_numeric(implode('', $originalKeys)); + if ($numeric) { + $data = array_values($data); + } + $sortValues = self::extract($data, $path); + $sortCount = count($sortValues); + $dataCount = count($data); + + // Make sortValues match the data length, as some keys could be missing + // the sorted value path. + if ($sortCount < $dataCount) { + $sortValues = array_pad($sortValues, $dataCount, null); + } + $result = self::_squash($sortValues); + $keys = self::extract($result, '{n}.id'); + $values = self::extract($result, '{n}.value'); + + $dir = strtolower($dir); + $type = strtolower($type); + if ($type == 'natural' && version_compare(PHP_VERSION, '5.4.0', '<')) { + $type == 'regular'; + } + if ($dir === 'asc') { + $dir = SORT_ASC; + } else { + $dir = SORT_DESC; + } + if ($type === 'numeric') { + $type = SORT_NUMERIC; + } elseif ($type === 'string') { + $type = SORT_STRING; + } elseif ($type === 'natural') { + $type = SORT_NATURAL; + } else { + $type = SORT_REGULAR; + } + array_multisort($values, $dir, $type, $keys, $dir, $type); + $sorted = array(); + $keys = array_unique($keys); + + foreach ($keys as $k) { + if ($numeric) { + $sorted[] = $data[$k]; + continue; + } + if (isset($originalKeys[$k])) { + $sorted[$originalKeys[$k]] = $data[$originalKeys[$k]]; + } else { + $sorted[$k] = $data[$k]; + } + } + return $sorted; + } + +/** + * Helper method for sort() + * Sqaushes an array to a single hash so it can be sorted. + * + * @param array $data The data to squash. + * @param string $key The key for the data. + * @return array + */ + protected static function _squash($data, $key = null) { + $stack = array(); + foreach ($data as $k => $r) { + $id = $k; + if (!is_null($key)) { + $id = $key; + } + if (is_array($r) && !empty($r)) { + $stack = array_merge($stack, self::_squash($r, $id)); + } else { + $stack[] = array('id' => $id, 'value' => $r); + } + } + return $stack; + } + +/** + * Computes the difference between two complex arrays. + * This method differs from the built-in array_diff() in that it will preserve keys + * and work on multi-dimensional arrays. + * + * @param array $data First value + * @param array $compare Second value + * @return array Returns the key => value pairs that are not common in $data and $compare + * The expression for this function is ($data - $compare) + ($compare - ($data - $compare)) + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::diff + */ + public static function diff(array $data, $compare) { + if (empty($data)) { + return (array)$compare; + } + if (empty($compare)) { + return (array)$data; + } + $intersection = array_intersect_key($data, $compare); + while (($key = key($intersection)) !== null) { + if ($data[$key] == $compare[$key]) { + unset($data[$key]); + unset($compare[$key]); + } + next($intersection); + } + return $data + $compare; + } + +/** + * Merges the difference between $data and $push onto $data. + * + * @param array $data The data to append onto. + * @param array $compare The data to compare and append onto. + * @return array The merged array. + */ + public static function mergeDiff(array $data, $compare) { + if (empty($data) && !empty($compare)) { + return $compare; + } + if (empty($compare)) { + return $data; + } + foreach ($compare as $key => $value) { + if (!array_key_exists($key, $data)) { + $data[$key] = $value; + } elseif (is_array($value)) { + $data[$key] = self::mergeDiff($data[$key], $compare[$key]); + } + } + return $data; + } + +/** + * Normalizes an array, and converts it to a standard format. + * + * @param array $data List to normalize + * @param boolean $assoc If true, $data will be converted to an associative array. + * @return array + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::normalize + */ + public static function normalize(array $data, $assoc = true) { + $keys = array_keys($data); + $count = count($keys); + $numeric = true; + + if (!$assoc) { + for ($i = 0; $i < $count; $i++) { + if (!is_int($keys[$i])) { + $numeric = false; + break; + } + } + } + if (!$numeric || $assoc) { + $newList = array(); + for ($i = 0; $i < $count; $i++) { + if (is_int($keys[$i])) { + $newList[$data[$keys[$i]]] = null; + } else { + $newList[$keys[$i]] = $data[$keys[$i]]; + } + } + $data = $newList; + } + return $data; + } + +/** + * Takes in a flat array and returns a nested array + * + * ### Options: + * + * - `children` The key name to use in the resultset for children. + * - `idPath` The path to a key that identifies each entry. Should be + * compatible with Hash::extract(). Defaults to `{n}.$alias.id` + * - `parentPath` The path to a key that identifies the parent of each entry. + * Should be compatible with Hash::extract(). Defaults to `{n}.$alias.parent_id` + * - `root` The id of the desired top-most result. + * + * @param array $data The data to nest. + * @param array $options Options are: + * @return array of results, nested + * @see Hash::extract() + */ + public static function nest(array $data, $options = array()) { + if (!$data) { + return $data; + } + + $alias = key(current($data)); + $options += array( + 'idPath' => "{n}.$alias.id", + 'parentPath' => "{n}.$alias.parent_id", + 'children' => 'children', + 'root' => null + ); + + $return = $idMap = array(); + $ids = self::extract($data, $options['idPath']); + + $idKeys = explode('.', $options['idPath']); + array_shift($idKeys); + + $parentKeys = explode('.', $options['parentPath']); + array_shift($parentKeys); + + foreach ($data as $result) { + $result[$options['children']] = array(); + + $id = self::get($result, $idKeys); + $parentId = self::get($result, $parentKeys); + + if (isset($idMap[$id][$options['children']])) { + $idMap[$id] = array_merge($result, (array)$idMap[$id]); + } else { + $idMap[$id] = array_merge($result, array($options['children'] => array())); + } + if (!$parentId || !in_array($parentId, $ids)) { + $return[] =& $idMap[$id]; + } else { + $idMap[$parentId][$options['children']][] =& $idMap[$id]; + } + } + + if ($options['root']) { + $root = $options['root']; + } else { + $root = self::get($return[0], $parentKeys); + } + + foreach ($return as $i => $result) { + $id = self::get($result, $idKeys); + $parentId = self::get($result, $parentKeys); + if ($id !== $root && $parentId != $root) { + unset($return[$i]); + } + } + return array_values($return); + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php new file mode 100644 index 0000000..31829d6 --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Inflector.php @@ -0,0 +1,551 @@ + array( + '/(s)tatus$/i' => '\1\2tatuses', + '/(quiz)$/i' => '\1zes', + '/^(ox)$/i' => '\1\2en', + '/([m|l])ouse$/i' => '\1ice', + '/(matr|vert|ind)(ix|ex)$/i' => '\1ices', + '/(x|ch|ss|sh)$/i' => '\1es', + '/([^aeiouy]|qu)y$/i' => '\1ies', + '/(hive)$/i' => '\1s', + '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', + '/sis$/i' => 'ses', + '/([ti])um$/i' => '\1a', + '/(p)erson$/i' => '\1eople', + '/(m)an$/i' => '\1en', + '/(c)hild$/i' => '\1hildren', + '/(buffal|tomat)o$/i' => '\1\2oes', + '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i', + '/us$/i' => 'uses', + '/(alias)$/i' => '\1es', + '/(ax|cris|test)is$/i' => '\1es', + '/s$/' => 's', + '/^$/' => '', + '/$/' => 's', + ), + 'uninflected' => array( + '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people' + ), + 'irregular' => array( + 'atlas' => 'atlases', + 'beef' => 'beefs', + 'brother' => 'brothers', + 'cafe' => 'cafes', + 'child' => 'children', + 'corpus' => 'corpuses', + 'cow' => 'cows', + 'ganglion' => 'ganglions', + 'genie' => 'genies', + 'genus' => 'genera', + 'graffito' => 'graffiti', + 'hoof' => 'hoofs', + 'loaf' => 'loaves', + 'man' => 'men', + 'money' => 'monies', + 'mongoose' => 'mongooses', + 'move' => 'moves', + 'mythos' => 'mythoi', + 'niche' => 'niches', + 'numen' => 'numina', + 'occiput' => 'occiputs', + 'octopus' => 'octopuses', + 'opus' => 'opuses', + 'ox' => 'oxen', + 'penis' => 'penises', + 'person' => 'people', + 'sex' => 'sexes', + 'soliloquy' => 'soliloquies', + 'testis' => 'testes', + 'trilby' => 'trilbys', + 'turf' => 'turfs' + ) + ); + +/** + * Singular inflector rules + * + * @var array + */ + protected static $_singular = array( + 'rules' => array( + '/(s)tatuses$/i' => '\1\2tatus', + '/^(.*)(menu)s$/i' => '\1\2', + '/(quiz)zes$/i' => '\\1', + '/(matr)ices$/i' => '\1ix', + '/(vert|ind)ices$/i' => '\1ex', + '/^(ox)en/i' => '\1', + '/(alias)(es)*$/i' => '\1', + '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us', + '/([ftw]ax)es/i' => '\1', + '/(cris|ax|test)es$/i' => '\1is', + '/(shoe|slave)s$/i' => '\1', + '/(o)es$/i' => '\1', + '/ouses$/' => 'ouse', + '/([^a])uses$/' => '\1us', + '/([m|l])ice$/i' => '\1ouse', + '/(x|ch|ss|sh)es$/i' => '\1', + '/(m)ovies$/i' => '\1\2ovie', + '/(s)eries$/i' => '\1\2eries', + '/([^aeiouy]|qu)ies$/i' => '\1y', + '/([lr])ves$/i' => '\1f', + '/(tive)s$/i' => '\1', + '/(hive)s$/i' => '\1', + '/(drive)s$/i' => '\1', + '/([^fo])ves$/i' => '\1fe', + '/(^analy)ses$/i' => '\1sis', + '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', + '/([ti])a$/i' => '\1um', + '/(p)eople$/i' => '\1\2erson', + '/(m)en$/i' => '\1an', + '/(c)hildren$/i' => '\1\2hild', + '/(n)ews$/i' => '\1\2ews', + '/eaus$/' => 'eau', + '/^(.*us)$/' => '\\1', + '/s$/i' => '' + ), + 'uninflected' => array( + '.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss' + ), + 'irregular' => array( + 'foes' => 'foe', + 'waves' => 'wave', + 'curves' => 'curve' + ) + ); + +/** + * Words that should not be inflected + * + * @var array + */ + protected static $_uninflected = array( + 'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', + 'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', + 'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder', + 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti', + 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', + 'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media', + 'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese', + 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', + 'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', + 'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'swine', 'testes', + 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', 'wildebeest', + 'Yengeese' + ); + +/** + * Default map of accented and special characters to ASCII characters + * + * @var array + */ + protected static $_transliteration = array( + '/ä|æ|ǽ/' => 'ae', + '/ö|œ/' => 'oe', + '/ü/' => 'ue', + '/Ä/' => 'Ae', + '/Ü/' => 'Ue', + '/Ö/' => 'Oe', + '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A', + '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a', + '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', + '/ç|ć|ĉ|ċ|č/' => 'c', + '/Ð|Ď|Đ/' => 'D', + '/ð|ď|đ/' => 'd', + '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E', + '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e', + '/Ĝ|Ğ|Ġ|Ģ/' => 'G', + '/ĝ|ğ|ġ|ģ/' => 'g', + '/Ĥ|Ħ/' => 'H', + '/ĥ|ħ/' => 'h', + '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I', + '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i', + '/Ĵ/' => 'J', + '/ĵ/' => 'j', + '/Ķ/' => 'K', + '/ķ/' => 'k', + '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L', + '/ĺ|ļ|ľ|ŀ|ł/' => 'l', + '/Ñ|Ń|Ņ|Ň/' => 'N', + '/ñ|ń|ņ|ň|ʼn/' => 'n', + '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O', + '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o', + '/Ŕ|Ŗ|Ř/' => 'R', + '/ŕ|ŗ|ř/' => 'r', + '/Ś|Ŝ|Ş|Š/' => 'S', + '/ś|ŝ|ş|š|ſ/' => 's', + '/Ţ|Ť|Ŧ/' => 'T', + '/ţ|ť|ŧ/' => 't', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U', + '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u', + '/Ý|Ÿ|Ŷ/' => 'Y', + '/ý|ÿ|ŷ/' => 'y', + '/Ŵ/' => 'W', + '/ŵ/' => 'w', + '/Ź|Ż|Ž/' => 'Z', + '/ź|ż|ž/' => 'z', + '/Æ|Ǽ/' => 'AE', + '/ß/' => 'ss', + '/IJ/' => 'IJ', + '/ij/' => 'ij', + '/Œ/' => 'OE', + '/ƒ/' => 'f' + ); + +/** + * Method cache array. + * + * @var array + */ + protected static $_cache = array(); + +/** + * The initial state of Inflector so reset() works. + * + * @var array + */ + protected static $_initialState = array(); + +/** + * Cache inflected values, and return if already available + * + * @param string $type Inflection type + * @param string $key Original value + * @param string $value Inflected value + * @return string Inflected value, from cache + */ + protected static function _cache($type, $key, $value = false) { + $key = '_' . $key; + $type = '_' . $type; + if ($value !== false) { + self::$_cache[$type][$key] = $value; + return $value; + } + if (!isset(self::$_cache[$type][$key])) { + return false; + } + return self::$_cache[$type][$key]; + } + +/** + * Clears Inflectors inflected value caches. And resets the inflection + * rules to the initial values. + * + * @return void + */ + public static function reset() { + if (empty(self::$_initialState)) { + self::$_initialState = get_class_vars('Inflector'); + return; + } + foreach (self::$_initialState as $key => $val) { + if ($key != '_initialState') { + self::${$key} = $val; + } + } + } + +/** + * Adds custom inflection $rules, of either 'plural', 'singular' or 'transliteration' $type. + * + * ### Usage: + * + * {{{ + * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables')); + * Inflector::rules('plural', array( + * 'rules' => array('/^(inflect)ors$/i' => '\1ables'), + * 'uninflected' => array('dontinflectme'), + * 'irregular' => array('red' => 'redlings') + * )); + * Inflector::rules('transliteration', array('/å/' => 'aa')); + * }}} + * + * @param string $type The type of inflection, either 'plural', 'singular' or 'transliteration' + * @param array $rules Array of rules to be added. + * @param boolean $reset If true, will unset default inflections for all + * new rules that are being defined in $rules. + * @return void + */ + public static function rules($type, $rules, $reset = false) { + $var = '_' . $type; + + switch ($type) { + case 'transliteration': + if ($reset) { + self::$_transliteration = $rules; + } else { + self::$_transliteration = $rules + self::$_transliteration; + } + break; + + default: + foreach ($rules as $rule => $pattern) { + if (is_array($pattern)) { + if ($reset) { + self::${$var}[$rule] = $pattern; + } else { + if ($rule === 'uninflected') { + self::${$var}[$rule] = array_merge($pattern, self::${$var}[$rule]); + } else { + self::${$var}[$rule] = $pattern + self::${$var}[$rule]; + } + } + unset($rules[$rule], self::${$var}['cache' . ucfirst($rule)]); + if (isset(self::${$var}['merged'][$rule])) { + unset(self::${$var}['merged'][$rule]); + } + if ($type === 'plural') { + self::$_cache['pluralize'] = self::$_cache['tableize'] = array(); + } elseif ($type === 'singular') { + self::$_cache['singularize'] = array(); + } + } + } + self::${$var}['rules'] = $rules + self::${$var}['rules']; + break; + } + } + +/** + * Return $word in plural form. + * + * @param string $word Word in singular + * @return string Word in plural + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::pluralize + */ + public static function pluralize($word) { + if (isset(self::$_cache['pluralize'][$word])) { + return self::$_cache['pluralize'][$word]; + } + + if (!isset(self::$_plural['merged']['irregular'])) { + self::$_plural['merged']['irregular'] = self::$_plural['irregular']; + } + + if (!isset(self::$_plural['merged']['uninflected'])) { + self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected); + } + + if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) { + self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')'; + self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')'; + } + + if (preg_match('/(.*)\\b(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) { + self::$_cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1); + return self::$_cache['pluralize'][$word]; + } + + if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) { + self::$_cache['pluralize'][$word] = $word; + return $word; + } + + foreach (self::$_plural['rules'] as $rule => $replacement) { + if (preg_match($rule, $word)) { + self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word); + return self::$_cache['pluralize'][$word]; + } + } + } + +/** + * Return $word in singular form. + * + * @param string $word Word in plural + * @return string Word in singular + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::singularize + */ + public static function singularize($word) { + if (isset(self::$_cache['singularize'][$word])) { + return self::$_cache['singularize'][$word]; + } + + if (!isset(self::$_singular['merged']['uninflected'])) { + self::$_singular['merged']['uninflected'] = array_merge( + self::$_singular['uninflected'], + self::$_uninflected + ); + } + + if (!isset(self::$_singular['merged']['irregular'])) { + self::$_singular['merged']['irregular'] = array_merge( + self::$_singular['irregular'], + array_flip(self::$_plural['irregular']) + ); + } + + if (!isset(self::$_singular['cacheUninflected']) || !isset(self::$_singular['cacheIrregular'])) { + self::$_singular['cacheUninflected'] = '(?:' . join('|', self::$_singular['merged']['uninflected']) . ')'; + self::$_singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$_singular['merged']['irregular'])) . ')'; + } + + if (preg_match('/(.*)\\b(' . self::$_singular['cacheIrregular'] . ')$/i', $word, $regs)) { + self::$_cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_singular['merged']['irregular'][strtolower($regs[2])], 1); + return self::$_cache['singularize'][$word]; + } + + if (preg_match('/^(' . self::$_singular['cacheUninflected'] . ')$/i', $word, $regs)) { + self::$_cache['singularize'][$word] = $word; + return $word; + } + + foreach (self::$_singular['rules'] as $rule => $replacement) { + if (preg_match($rule, $word)) { + self::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word); + return self::$_cache['singularize'][$word]; + } + } + self::$_cache['singularize'][$word] = $word; + return $word; + } + +/** + * Returns the given lower_case_and_underscored_word as a CamelCased word. + * + * @param string $lowerCaseAndUnderscoredWord Word to camelize + * @return string Camelized word. LikeThis. + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::camelize + */ + public static function camelize($lowerCaseAndUnderscoredWord) { + if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) { + $result = str_replace(' ', '', Inflector::humanize($lowerCaseAndUnderscoredWord)); + self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result); + } + return $result; + } + +/** + * Returns the given camelCasedWord as an underscored_word. + * + * @param string $camelCasedWord Camel-cased word to be "underscorized" + * @return string Underscore-syntaxed version of the $camelCasedWord + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::underscore + */ + public static function underscore($camelCasedWord) { + if (!($result = self::_cache(__FUNCTION__, $camelCasedWord))) { + $result = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord)); + self::_cache(__FUNCTION__, $camelCasedWord, $result); + } + return $result; + } + +/** + * Returns the given underscored_word_group as a Human Readable Word Group. + * (Underscores are replaced by spaces and capitalized following words.) + * + * @param string $lowerCaseAndUnderscoredWord String to be made more readable + * @return string Human-readable string + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::humanize + */ + public static function humanize($lowerCaseAndUnderscoredWord) { + if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) { + $result = ucwords(str_replace('_', ' ', $lowerCaseAndUnderscoredWord)); + self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result); + } + return $result; + } + +/** + * Returns corresponding table name for given model $className. ("people" for the model class "Person"). + * + * @param string $className Name of class to get database table name for + * @return string Name of the database table for given class + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::tableize + */ + public static function tableize($className) { + if (!($result = self::_cache(__FUNCTION__, $className))) { + $result = Inflector::pluralize(Inflector::underscore($className)); + self::_cache(__FUNCTION__, $className, $result); + } + return $result; + } + +/** + * Returns Cake model class name ("Person" for the database table "people".) for given database table. + * + * @param string $tableName Name of database table to get class name for + * @return string Class name + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::classify + */ + public static function classify($tableName) { + if (!($result = self::_cache(__FUNCTION__, $tableName))) { + $result = Inflector::camelize(Inflector::singularize($tableName)); + self::_cache(__FUNCTION__, $tableName, $result); + } + return $result; + } + +/** + * Returns camelBacked version of an underscored string. + * + * @param string $string + * @return string in variable form + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::variable + */ + public static function variable($string) { + if (!($result = self::_cache(__FUNCTION__, $string))) { + $camelized = Inflector::camelize(Inflector::underscore($string)); + $replace = strtolower(substr($camelized, 0, 1)); + $result = preg_replace('/\\w/', $replace, $camelized, 1); + self::_cache(__FUNCTION__, $string, $result); + } + return $result; + } + +/** + * Returns a string with all spaces converted to underscores (by default), accented + * characters converted to non-accented characters, and non word characters removed. + * + * @param string $string the string you want to slug + * @param string $replacement will replace keys in map + * @return string + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/inflector.html#Inflector::slug + */ + public static function slug($string, $replacement = '_') { + $quotedReplacement = preg_quote($replacement, '/'); + + $merge = array( + '/[^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ', + '/\\s+/' => $replacement, + sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '', + ); + + $map = self::$_transliteration + $merge; + return preg_replace(array_keys($map), array_values($map), $string); + } + +} + +// Store the initial state +Inflector::reset(); diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php new file mode 100644 index 0000000..96ec3d5 --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/ObjectCollection.php @@ -0,0 +1,326 @@ +_loaded`. Enabled objects are stored in `$this->_enabled`. In addition + * the all support an `enabled` option that controls the enabled/disabled state of the object + * when loaded. + * + * @package Cake.Utility + * @since CakePHP(tm) v 2.0 + */ +abstract class ObjectCollection { + +/** + * List of the currently-enabled objects + * + * @var array + */ + protected $_enabled = array(); + +/** + * A hash of loaded objects, indexed by name + * + * @var array + */ + protected $_loaded = array(); + +/** + * Default object priority. A non zero integer. + * + * @var int + */ + public $defaultPriority = 10; + +/** + * Loads a new object onto the collection. Can throw a variety of exceptions + * + * Implementations of this class support a `$options['enabled']` flag which enables/disables + * a loaded object. + * + * @param string $name Name of object to load. + * @param array $options Array of configuration options for the object to be constructed. + * @return object the constructed object + */ + abstract public function load($name, $options = array()); + +/** + * Trigger a callback method on every object in the collection. + * Used to trigger methods on objects in the collection. Will fire the methods in the + * order they were attached. + * + * ### Options + * + * - `breakOn` Set to the value or values you want the callback propagation to stop on. + * Can either be a scalar value, or an array of values to break on. Defaults to `false`. + * + * - `break` Set to true to enabled breaking. When a trigger is broken, the last returned value + * will be returned. If used in combination with `collectReturn` the collected results will be returned. + * Defaults to `false`. + * + * - `collectReturn` Set to true to collect the return of each object into an array. + * This array of return values will be returned from the trigger() call. Defaults to `false`. + * + * - `modParams` Allows each object the callback gets called on to modify the parameters to the next object. + * Setting modParams to an integer value will allow you to modify the parameter with that index. + * Any non-null value will modify the parameter index indicated. + * Defaults to false. + * + * + * @param string $callback|CakeEvent Method to fire on all the objects. Its assumed all the objects implement + * the method you are calling. If an instance of CakeEvent is provided, then then Event name will parsed to + * get the callback name. This is done by getting the last word after any dot in the event name + * (eg. `Model.afterSave` event will trigger the `afterSave` callback) + * @param array $params Array of parameters for the triggered callback. + * @param array $options Array of options. + * @return mixed Either the last result or all results if collectReturn is on. + * @throws CakeException when modParams is used with an index that does not exist. + */ + public function trigger($callback, $params = array(), $options = array()) { + if (empty($this->_enabled)) { + return true; + } + if ($callback instanceof CakeEvent) { + $event = $callback; + if (is_array($event->data)) { + $params =& $event->data; + } + if (empty($event->omitSubject)) { + $subject = $event->subject(); + } + //TODO: Temporary BC check, while we move all the triggers system into the CakeEventManager + foreach (array('break', 'breakOn', 'collectReturn', 'modParams') as $opt) { + if (isset($event->{$opt})) { + $options[$opt] = $event->{$opt}; + } + } + $parts = explode('.', $event->name()); + $callback = array_pop($parts); + } + $options = array_merge( + array( + 'break' => false, + 'breakOn' => false, + 'collectReturn' => false, + 'modParams' => false + ), + $options + ); + $collected = array(); + $list = array_keys($this->_enabled); + if ($options['modParams'] !== false && !isset($params[$options['modParams']])) { + throw new CakeException(__d('cake_dev', 'Cannot use modParams with indexes that do not exist.')); + } + foreach ($list as $name) { + $result = call_user_func_array(array($this->_loaded[$name], $callback), compact('subject') + $params); + if ($options['collectReturn'] === true) { + $collected[] = $result; + } + if ( + $options['break'] && ($result === $options['breakOn'] || + (is_array($options['breakOn']) && in_array($result, $options['breakOn'], true))) + ) { + return $result; + } elseif ($options['modParams'] !== false && !in_array($result, array(true, false, null), true)) { + $params[$options['modParams']] = $result; + } + } + if ($options['modParams'] !== false) { + return $params[$options['modParams']]; + } + return $options['collectReturn'] ? $collected : $result; + } + +/** + * Provide public read access to the loaded objects + * + * @param string $name Name of property to read + * @return mixed + */ + public function __get($name) { + if (isset($this->_loaded[$name])) { + return $this->_loaded[$name]; + } + return null; + } + +/** + * Provide isset access to _loaded + * + * @param string $name Name of object being checked. + * @return boolean + */ + public function __isset($name) { + return isset($this->_loaded[$name]); + } + +/** + * Enables callbacks on an object or array of objects + * + * @param string|array $name CamelCased name of the object(s) to enable (string or array) + * @param boolean Prioritize enabled list after enabling object(s) + * @return void + */ + public function enable($name, $prioritize = true) { + $enabled = false; + foreach ((array)$name as $object) { + if (isset($this->_loaded[$object]) && !isset($this->_enabled[$object])) { + $priority = isset($this->_loaded[$object]->settings['priority']) ? $this->_loaded[$object]->settings['priority'] : $this->defaultPriority; + $this->_enabled[$object] = array($priority); + $enabled = true; + } + } + if ($prioritize && $enabled) { + $this->prioritize(); + } + } + +/** + * Prioritize list of enabled object + * + * @return array Prioritized list of object + */ + public function prioritize() { + $i = 1; + foreach ($this->_enabled as $name => $priority) { + $priority[1] = $i++; + $this->_enabled[$name] = $priority; + } + asort($this->_enabled); + return $this->_enabled; + } + +/** + * Set priority for an object or array of objects + * + * @param string|array $name CamelCased name of the object(s) to enable (string or array) + * If string the second param $priority is used else it should be an associative array + * with keys as object names and values as priorities to set. + * @param integer|null Integer priority to set or null for default + * @return void + */ + public function setPriority($name, $priority = null) { + if (is_string($name)) { + $name = array($name => $priority); + } + foreach ($name as $obj => $prio) { + if (isset($this->_loaded[$obj])) { + if (is_null($prio)) { + $prio = $this->defaultPriority; + } + $this->_loaded[$obj]->settings['priority'] = $prio; + if (isset($this->_enabled[$obj])) { + $this->_enabled[$obj] = array($prio); + } + } + } + $this->prioritize(); + } + +/** + * Disables callbacks on a object or array of objects. Public object methods are still + * callable as normal. + * + * @param string|array $name CamelCased name of the objects(s) to disable (string or array) + * @return void + */ + public function disable($name) { + foreach ((array)$name as $object) { + unset($this->_enabled[$object]); + } + } + +/** + * Gets the list of currently-enabled objects, or, the current status of a single objects + * + * @param string $name Optional. The name of the object to check the status of. If omitted, + * returns an array of currently-enabled object + * @return mixed If $name is specified, returns the boolean status of the corresponding object. + * Otherwise, returns an array of all enabled objects. + */ + public function enabled($name = null) { + if (!empty($name)) { + return isset($this->_enabled[$name]); + } + return array_keys($this->_enabled); + } + +/** + * Gets the list of attached objects, or, whether the given object is attached + * + * @param string $name Optional. The name of the behavior to check the status of. If omitted, + * returns an array of currently-attached behaviors + * @return mixed If $name is specified, returns the boolean status of the corresponding behavior. + * Otherwise, returns an array of all attached behaviors. + */ + public function attached($name = null) { + if (!empty($name)) { + return isset($this->_loaded[$name]); + } + return array_keys($this->_loaded); + } + +/** + * Name of the object to remove from the collection + * + * @param string $name Name of the object to delete. + * @return void + */ + public function unload($name) { + list($plugin, $name) = pluginSplit($name); + unset($this->_loaded[$name]); + unset($this->_enabled[$name]); + } + +/** + * Adds or overwrites an instantiated object to the collection + * + * @param string $name Name of the object + * @param Object $object The object to use + * @return array Loaded objects + */ + public function set($name = null, $object = null) { + if (!empty($name) && !empty($object)) { + list($plugin, $name) = pluginSplit($name); + $this->_loaded[$name] = $object; + } + return $this->_loaded; + } + +/** + * Normalizes an object array, creates an array that makes lazy loading + * easier + * + * @param array $objects Array of child objects to normalize. + * @return array Array of normalized objects. + */ + public static function normalizeObjectArray($objects) { + $normal = array(); + foreach ($objects as $i => $objectName) { + $options = array(); + if (!is_int($i)) { + $options = (array)$objectName; + $objectName = $i; + } + list($plugin, $name) = pluginSplit($objectName); + $normal[$name] = array('class' => $objectName, 'settings' => $options); + } + return $normal; + } + +} diff --git a/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php new file mode 100644 index 0000000..dfb55f3 --- /dev/null +++ b/poc/poc02-compiling-cake/src/vendor/cakephp-2.2.1-0-gcc44130/lib/Cake/Utility/Sanitize.php @@ -0,0 +1,264 @@ + $clean) { + $cleaned[$key] = preg_replace("/[^{$allow}a-zA-Z0-9]/", '', $clean); + } + } else { + $cleaned = preg_replace("/[^{$allow}a-zA-Z0-9]/", '', $string); + } + return $cleaned; + } + +/** + * Makes a string SQL-safe. + * + * @param string $string String to sanitize + * @param string $connection Database connection being used + * @return string SQL safe string + */ + public static function escape($string, $connection = 'default') { + $db = ConnectionManager::getDataSource($connection); + if (is_numeric($string) || $string === null || is_bool($string)) { + return $string; + } + $string = $db->value($string, 'string'); + if ($string[0] === 'N') { + $string = substr($string, 2); + } else { + $string = substr($string, 1); + } + + $string = substr($string, 0, -1); + return $string; + } + +/** + * Returns given string safe for display as HTML. Renders entities. + * + * strip_tags() does not validating HTML syntax or structure, so it might strip whole passages + * with broken HTML. + * + * ### Options: + * + * - remove (boolean) if true strips all HTML tags before encoding + * - charset (string) the charset used to encode the string + * - quotes (int) see http://php.net/manual/en/function.htmlentities.php + * - double (boolean) doube encode html entities + * + * @param string $string String from where to strip tags + * @param array $options Array of options to use. + * @return string Sanitized string + */ + public static function html($string, $options = array()) { + static $defaultCharset = false; + if ($defaultCharset === false) { + $defaultCharset = Configure::read('App.encoding'); + if ($defaultCharset === null) { + $defaultCharset = 'UTF-8'; + } + } + $default = array( + 'remove' => false, + 'charset' => $defaultCharset, + 'quotes' => ENT_QUOTES, + 'double' => true + ); + + $options = array_merge($default, $options); + + if ($options['remove']) { + $string = strip_tags($string); + } + + return htmlentities($string, $options['quotes'], $options['charset'], $options['double']); + } + +/** + * Strips extra whitespace from output + * + * @param string $str String to sanitize + * @return string whitespace sanitized string + */ + public static function stripWhitespace($str) { + $r = preg_replace('/[\n\r\t]+/', '', $str); + return preg_replace('/\s{2,}/u', ' ', $r); + } + +/** + * Strips image tags from output + * + * @param string $str String to sanitize + * @return string Sting with images stripped. + */ + public static function stripImages($str) { + $str = preg_replace('/(]*>)(]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5
', $str); + $str = preg_replace('/(]+alt=")([^"]*)("[^>]*>)/i', '$2
', $str); + $str = preg_replace('/]*>/i', '', $str); + return $str; + } + +/** + * Strips scripts and stylesheets from output + * + * @param string $str String to sanitize + * @return string String with