Browse Source

Merge branch '2.1-helper-refactor2' into 2.1

Rachman Chavik 14 years ago
parent
commit
5d9598673e

+ 5 - 0
lib/Cake/Test/Case/Utility/CakeTimeTest.php

@@ -328,6 +328,11 @@ class CakeTimeTest extends CakeTestCase {
 
 		$this->Time->niceFormat = '%Y-%d-%m';
 		$this->assertEquals(date('Y-d-m', $time), $this->Time->nice($time));
+		$this->assertEquals('%Y-%d-%m', $this->Time->niceFormat);
+
+		CakeTime::$niceFormat = '%Y-%d-%m %H:%M:%S';
+		$this->assertEquals(date('Y-d-m H:i:s', $time), $this->Time->nice($time));
+		$this->assertEquals('%Y-%d-%m %H:%M:%S', $this->Time->niceFormat);
 	}
 
 /**

+ 14 - 8
lib/Cake/Test/Case/View/Helper/NumberHelperTest.php

@@ -25,13 +25,19 @@ App::uses('NumberHelper', 'View/Helper');
  */
 class NumberHelperTestObject extends NumberHelper {
 
-	public function attach(CakeNumber $cakeNumber) {
+	public function attach(CakeNumberMock $cakeNumber) {
 		$this->_CakeNumber = $cakeNumber;
 	}
 
 }
 
 /**
+ * CakeNumberMock class
+ */
+class CakeNumberMock {
+}
+
+/**
  * NumberHelperTest class
  *
  * @package       Cake.Test.Case.View.Helper
@@ -45,10 +51,7 @@ class NumberHelperTest extends CakeTestCase {
  */
 	public function setUp() {
 		parent::setUp();
-		$view = $this->getMock('View', array(), array(), '', false);
-		$this->CakeNumber = $this->getMock('CakeNumber');
-		$this->Number = new NumberHelperTestObject($view);
-		$this->Number->attach($this->CakeNumber);
+		$this->View = new View(null);
 	}
 
 /**
@@ -58,7 +61,7 @@ class NumberHelperTest extends CakeTestCase {
  */
 	public function tearDown() {
 		parent::tearDown();
-		unset($this->Number);
+		unset($this->View);
 	}
 
 
@@ -70,9 +73,12 @@ class NumberHelperTest extends CakeTestCase {
 			'precision', 'toReadableSize', 'toPercentage', 'format',
 			'currency', 'addFormat',
 			);
+		$CakeNumber = $this->getMock('CakeNumberMock', $methods);
+		$Number = new NumberHelperTestObject($this->View, array('engine' => 'CakeNumberMock'));
+		$Number->attach($CakeNumber);
 		foreach ($methods as $method) {
-			$this->CakeNumber->expects($this->at(0))->method($method);
-			$this->Number->{$method}('who', 'what', 'when', 'where', 'how');
+			$CakeNumber->expects($this->at(0))->method($method);
+			$Number->{$method}('who', 'what', 'when', 'where', 'how');
 		}
 	}
 

+ 16 - 10
lib/Cake/Test/Case/View/Helper/TextHelperTest.php

@@ -22,13 +22,19 @@ App::uses('TextHelper', 'View/Helper');
 
 class TextHelperTestObject extends TextHelper {
 
-	public function attach(String $string) {
+	public function attach(StringMock $string) {
 		$this->_String = $string;
 	}
 
 }
 
 /**
+ * StringMock class
+ */
+class StringMock {
+}
+
+/**
  * TextHelperTest class
  *
  * @package       Cake.Test.Case.View.Helper
@@ -41,8 +47,8 @@ class TextHelperTest extends CakeTestCase {
  * @return void
  */
 	public function setUp() {
-		$controller = null;
-		$this->View = new View($controller);
+		parent::setUp();
+		$this->View = new View(null);
 		$this->Text = new TextHelper($this->View);
 	}
 
@@ -52,23 +58,23 @@ class TextHelperTest extends CakeTestCase {
  * @return void
  */
 	public function tearDown() {
-		unset($this->View, $this->Text);
+		unset($this->View);
+		parent::tearDown();
 	}
 
 /**
  * test String class methods are called correctly
  */
 	public function testTextHelperProxyMethodCalls() {
-		$this->String = $this->getMock('String');
-		unset($this->Text);
-		$this->Text = new TextHelperTestObject($this->View);
-		$this->Text->attach($this->String);
 		$methods = array(
 			'highlight', 'stripLinks', 'truncate', 'excerpt', 'toList',
 			);
+		$String = $this->getMock('StringMock', $methods);
+		$Text = new TextHelperTestObject($this->View, array('engine' => 'StringMock'));
+		$Text->attach($String);
 		foreach ($methods as $method) {
-			$this->String->expects($this->at(0))->method($method);
-			$this->Text->{$method}('who', 'what', 'when', 'where', 'how');
+			$String->expects($this->at(0))->method($method);
+			$Text->{$method}('who', 'what', 'when', 'where', 'how');
 		}
 	}
 

+ 16 - 9
lib/Cake/Test/Case/View/Helper/TimeHelperTest.php

@@ -25,13 +25,19 @@ App::uses('CakeTime', 'Utility');
  */
 class TimeHelperTestObject extends TimeHelper {
 
-	public function attach(CakeTime $cakeTime) {
+	public function attach(CakeTimeMock $cakeTime) {
 		$this->_CakeTime = $cakeTime;
 	}
 
 }
 
 /**
+ * CakeTimeMock class
+ */
+class CakeTimeMock {
+}
+
+/**
  * TimeHelperTest class
  *
  * @package       Cake.Test.Case.View.Helper
@@ -48,10 +54,8 @@ class TimeHelperTest extends CakeTestCase {
  * @return void
  */
 	public function setUp() {
-		$View = new View(null);
-		$this->CakeTime = $this->getMock('CakeTime');
-		$this->Time = new TimeHelperTestObject($View);
-		$this->Time->attach($this->CakeTime);
+		parent::setUp();
+		$this->View = new View(null);
 	}
 
 /**
@@ -60,8 +64,8 @@ class TimeHelperTest extends CakeTestCase {
  * @return void
  */
 	public function tearDown() {
-		unset($this->Time);
-		unset($this->CakeTime);
+		unset($this->View);
+		parent::tearDown();
 	}
 
 /**
@@ -75,9 +79,12 @@ class TimeHelperTest extends CakeTestCase {
 			'isTomorrow', 'toQuarter', 'toUnix', 'toAtom', 'toRSS',
 			'timeAgoInWords', 'wasWithinLast', 'gmt', 'format', 'i18nFormat',
 			);
+		$CakeTime = $this->getMock('CakeTimeMock', $methods);
+		$Time = new TimeHelperTestObject($this->View, array('engine' => 'CakeTimeMock'));
+		$Time->attach($CakeTime);
 		foreach ($methods as $method) {
-			$this->CakeTime->expects($this->at(0))->method($method);
-			$this->Time->{$method}('who', 'what', 'when', 'where', 'how');
+			$CakeTime->expects($this->at(0))->method($method);
+			$Time->{$method}('who', 'what', 'when', 'where', 'how');
 		}
 	}
 

+ 12 - 12
lib/Cake/Utility/CakeNumber.php

@@ -68,7 +68,7 @@ class CakeNumber {
  * @return float Formatted float.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::precision
  */
-	public function precision($number, $precision = 3) {
+	public static function precision($number, $precision = 3) {
 		return sprintf("%01.{$precision}f", $number);
 	}
 
@@ -79,18 +79,18 @@ class CakeNumber {
  * @return string Human readable size
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
  */
-	public function toReadableSize($size) {
+	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', $this->precision($size / 1024, 0));
+				return __d('cake', '%d KB', self::precision($size / 1024, 0));
 			case round($size / 1024 / 1024, 2) < 1024:
-				return __d('cake', '%.2f MB', $this->precision($size / 1024 / 1024, 2));
+				return __d('cake', '%.2f MB', self::precision($size / 1024 / 1024, 2));
 			case round($size / 1024 / 1024 / 1024, 2) < 1024:
-				return __d('cake', '%.2f GB', $this->precision($size / 1024 / 1024 / 1024, 2));
+				return __d('cake', '%.2f GB', self::precision($size / 1024 / 1024 / 1024, 2));
 			default:
-				return __d('cake', '%.2f TB', $this->precision($size / 1024 / 1024 / 1024 / 1024, 2));
+				return __d('cake', '%.2f TB', self::precision($size / 1024 / 1024 / 1024 / 1024, 2));
 		}
 	}
 
@@ -102,8 +102,8 @@ class CakeNumber {
  * @return string Percentage string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toPercentage
  */
-	public function toPercentage($number, $precision = 2) {
-		return $this->precision($number, $precision) . '%';
+	public static function toPercentage($number, $precision = 2) {
+		return self::precision($number, $precision) . '%';
 	}
 
 /**
@@ -115,7 +115,7 @@ class CakeNumber {
  * @return string formatted number
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::format
  */
-	public function format($number, $options = false) {
+	public static function format($number, $options = false) {
 		$places = 0;
 		if (is_int($options)) {
 			$places = $options;
@@ -172,7 +172,7 @@ class CakeNumber {
  * @return string Number formatted as a currency.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::currency
  */
-	public function currency($number, $currency = 'USD', $options = array()) {
+	public static function currency($number, $currency = 'USD', $options = array()) {
 		$default = self::$_currencyDefaults;
 
 		if (isset(self::$_currencies[$currency])) {
@@ -210,7 +210,7 @@ class CakeNumber {
 		$options[$position] = $options[$symbolKey.'Symbol'];
 
 		$abs = abs($number);
-		$result = $this->format($abs, $options);
+		$result = self::format($abs, $options);
 
 		if ($number < 0 ) {
 			if ($options['negative'] == '()') {
@@ -247,7 +247,7 @@ class CakeNumber {
  * @see NumberHelper::currency()
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::addFormat
  */
-	public function addFormat($formatName, $options) {
+	public static function addFormat($formatName, $options) {
 		self::$_currencies[$formatName] = $options + self::$_currencyDefaults;
 	}
 

+ 117 - 81
lib/Cake/Utility/CakeTime.php

@@ -38,7 +38,43 @@ class CakeTime {
  * @var string
  * @see TimeHelper::format()
  */
-	public $niceFormat = '%a, %b %eS %Y, %H:%M';
+	public static $niceFormat = '%a, %b %eS %Y, %H:%M';
+
+/**
+ * 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
@@ -50,12 +86,12 @@ class CakeTime {
  * @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 function convertSpecifiers($format, $time = null) {
+	public static function convertSpecifiers($format, $time = null) {
 		if (!$time) {
 			$time = time();
 		}
-		$this->__time = $time;
-		return preg_replace_callback('/\%(\w+)/', array($this, '_translateSpecifier'), $format);
+		self::$_time = $time;
+		return preg_replace_callback('/\%(\w+)/', array('CakeTime', '_translateSpecifier'), $format);
 	}
 
 /**
@@ -70,47 +106,47 @@ class CakeTime {
 			case 'a':
 				$abday = __dc('cake', 'abday', 5);
 				if (is_array($abday)) {
-					return $abday[date('w', $this->__time)];
+					return $abday[date('w', self::$_time)];
 				}
 				break;
 			case 'A':
 				$day = __dc('cake', 'day', 5);
 				if (is_array($day)) {
-					return $day[date('w', $this->__time)];
+					return $day[date('w', self::$_time)];
 				}
 				break;
 			case 'c':
 				$format = __dc('cake', 'd_t_fmt', 5);
 				if ($format != 'd_t_fmt') {
-					return $this->convertSpecifiers($format, $this->__time);
+					return self::convertSpecifiers($format, self::$_time);
 				}
 				break;
 			case 'C':
-				return sprintf("%02d", date('Y', $this->__time) / 100);
+				return sprintf("%02d", date('Y', self::$_time) / 100);
 			case 'D':
 				return '%m/%d/%y';
 			case 'e':
 				if (DS === '/') {
 					return '%e';
 				}
-				$day = date('j', $this->__time);
+				$day = date('j', self::$_time);
 				if ($day < 10) {
 					$day = ' ' . $day;
 				}
 				return $day;
 			case 'eS' :
-				return date('jS', $this->__time);
+				return date('jS', self::$_time);
 			case 'b':
 			case 'h':
 				$months = __dc('cake', 'abmon', 5);
 				if (is_array($months)) {
-					return $months[date('n', $this->__time) -1];
+					return $months[date('n', self::$_time) -1];
 				}
 				return '%b';
 			case 'B':
 				$months = __dc('cake', 'mon', 5);
 				if (is_array($months)) {
-					return $months[date('n', $this->__time) -1];
+					return $months[date('n', self::$_time) -1];
 				}
 				break;
 			case 'n':
@@ -118,7 +154,7 @@ class CakeTime {
 			case 'p':
 			case 'P':
 				$default = array('am' => 0, 'pm' => 1);
-				$meridiem = $default[date('a', $this->__time)];
+				$meridiem = $default[date('a', self::$_time)];
 				$format = __dc('cake', 'am_pm', 5);
 				if (is_array($format)) {
 					$meridiem = $format[$meridiem];
@@ -128,27 +164,27 @@ class CakeTime {
 			case 'r':
 				$complete = __dc('cake', 't_fmt_ampm', 5);
 				if ($complete != 't_fmt_ampm') {
-					return str_replace('%p', $this->_translateSpecifier(array('%p', 'p')), $complete);
+					return str_replace('%p', self::_translateSpecifier(array('%p', 'p')), $complete);
 				}
 				break;
 			case 'R':
-				return date('H:i', $this->__time);
+				return date('H:i', self::$_time);
 			case 't':
 				return "\t";
 			case 'T':
 				return '%H:%M:%S';
 			case 'u':
-				return ($weekDay = date('w', $this->__time)) ? $weekDay : 7;
+				return ($weekDay = date('w', self::$_time)) ? $weekDay : 7;
 			case 'x':
 				$format = __dc('cake', 'd_fmt', 5);
 				if ($format != 'd_fmt') {
-					return $this->convertSpecifiers($format, $this->__time);
+					return self::convertSpecifiers($format, self::$_time);
 				}
 				break;
 			case 'X':
 				$format = __dc('cake', 't_fmt', 5);
 				if ($format != 't_fmt') {
-					return $this->convertSpecifiers($format, $this->__time);
+					return self::convertSpecifiers($format, self::$_time);
 				}
 				break;
 		}
@@ -163,8 +199,8 @@ class CakeTime {
  * @return integer UNIX timestamp
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function convert($serverTime, $userOffset) {
-		$serverOffset = $this->serverOffset();
+	public static function convert($serverTime, $userOffset) {
+		$serverOffset = self::serverOffset();
 		$gmtTime = $serverTime - $serverOffset;
 		$userTime = $gmtTime + $userOffset * (60*60);
 		return $userTime;
@@ -176,7 +212,7 @@ class CakeTime {
  * @return integer Offset
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function serverOffset() {
+	public static function serverOffset() {
 		return date('Z', time());
 	}
 
@@ -188,7 +224,7 @@ class CakeTime {
  * @return string Parsed timestamp
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function fromString($dateString, $userOffset = null) {
+	public static function fromString($dateString, $userOffset = null) {
 		if (empty($dateString)) {
 			return false;
 		}
@@ -198,7 +234,7 @@ class CakeTime {
 			$date = strtotime($dateString);
 		}
 		if ($userOffset !== null) {
-			return $this->convert($date, $userOffset);
+			return self::convert($date, $userOffset);
 		}
 		if ($date === -1) {
 			return false;
@@ -218,17 +254,17 @@ class CakeTime {
  * @return string Formatted date string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function nice($dateString = null, $userOffset = null, $format = null) {
+	public static function nice($dateString = null, $userOffset = null, $format = null) {
 		if ($dateString != null) {
-			$date = $this->fromString($dateString, $userOffset);
+			$date = self::fromString($dateString, $userOffset);
 		} else {
 			$date = time();
 		}
 		if (!$format) {
-			$format = $this->niceFormat;
+			$format = self::$niceFormat;
 		}
-		$format = $this->convertSpecifiers($format, $date);
-		return $this->_strftime($format, $date);
+		$format = self::convertSpecifiers($format, $date);
+		return self::_strftime($format, $date);
 	}
 
 /**
@@ -244,18 +280,18 @@ class CakeTime {
  * @return string Described, relative date string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function niceShort($dateString = null, $userOffset = null) {
-		$date = $dateString ? $this->fromString($dateString, $userOffset) : time();
+	public static function niceShort($dateString = null, $userOffset = null) {
+		$date = $dateString ? self::fromString($dateString, $userOffset) : time();
 
-		$y = $this->isThisYear($date) ? '' : ' %Y';
+		$y = self::isThisYear($date) ? '' : ' %Y';
 
-		if ($this->isToday($dateString, $userOffset)) {
-			$ret = __d('cake', 'Today, %s', $this->_strftime("%H:%M", $date));
-		} elseif ($this->wasYesterday($dateString, $userOffset)) {
-			$ret = __d('cake', 'Yesterday, %s', $this->_strftime("%H:%M", $date));
+		if (self::isToday($dateString, $userOffset)) {
+			$ret = __d('cake', 'Today, %s', self::_strftime("%H:%M", $date));
+		} elseif (self::wasYesterday($dateString, $userOffset)) {
+			$ret = __d('cake', 'Yesterday, %s', self::_strftime("%H:%M", $date));
 		} else {
-			$format = $this->convertSpecifiers("%b %eS{$y}, %H:%M", $date);
-			$ret = $this->_strftime($format, $date);
+			$format = self::convertSpecifiers("%b %eS{$y}, %H:%M", $date);
+			$ret = self::_strftime($format, $date);
 		}
 
 		return $ret;
@@ -271,9 +307,9 @@ class CakeTime {
  * @return string Partial SQL string.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function daysAsSql($begin, $end, $fieldName, $userOffset = null) {
-		$begin = $this->fromString($begin, $userOffset);
-		$end = $this->fromString($end, $userOffset);
+	public static function daysAsSql($begin, $end, $fieldName, $userOffset = null) {
+		$begin = self::fromString($begin, $userOffset);
+		$end = self::fromString($end, $userOffset);
 		$begin = date('Y-m-d', $begin) . ' 00:00:00';
 		$end = date('Y-m-d', $end) . ' 23:59:59';
 
@@ -290,9 +326,9 @@ class CakeTime {
  * @return string Partial SQL string.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function dayAsSql($dateString, $fieldName, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
-		return $this->daysAsSql($dateString, $dateString, $fieldName);
+	public static function dayAsSql($dateString, $fieldName, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
+		return self::daysAsSql($dateString, $dateString, $fieldName);
 	}
 
 /**
@@ -303,8 +339,8 @@ class CakeTime {
  * @return boolean True if datetime string is today
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
  */
-	public function isToday($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function isToday($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 		return date('Y-m-d', $date) == date('Y-m-d', time());
 	}
 
@@ -316,8 +352,8 @@ class CakeTime {
  * @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 function isThisWeek($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function isThisWeek($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 		return date('W o', $date) == date('W o', time());
 	}
 
@@ -328,8 +364,8 @@ class CakeTime {
  * @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 function isThisMonth($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString);
+	public static function isThisMonth($dateString, $userOffset = null) {
+		$date = self::fromString($dateString);
 		return date('m Y', $date) == date('m Y', time());
 	}
 
@@ -341,8 +377,8 @@ class CakeTime {
  * @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 function isThisYear($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function isThisYear($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 		return  date('Y', $date) == date('Y', time());
 	}
 
@@ -355,8 +391,8 @@ class CakeTime {
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
  *
  */
-	public function wasYesterday($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function wasYesterday($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 		return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday'));
 	}
 
@@ -368,8 +404,8 @@ class CakeTime {
  * @return boolean True if datetime string was yesterday
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
  */
-	public function isTomorrow($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function isTomorrow($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 		return date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow'));
 	}
 
@@ -381,8 +417,8 @@ class CakeTime {
  * @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 function toQuarter($dateString, $range = false) {
-		$time = $this->fromString($dateString);
+	public static function toQuarter($dateString, $range = false) {
+		$time = self::fromString($dateString);
 		$date = ceil(date('m', $time) / 3);
 
 		if ($range === true) {
@@ -418,8 +454,8 @@ class CakeTime {
  * @return integer Unix timestamp
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function toUnix($dateString, $userOffset = null) {
-		return $this->fromString($dateString, $userOffset);
+	public static function toUnix($dateString, $userOffset = null) {
+		return self::fromString($dateString, $userOffset);
 	}
 
 /**
@@ -430,8 +466,8 @@ class CakeTime {
  * @return string Formatted date string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function toAtom($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function toAtom($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 		return date('Y-m-d\TH:i:s\Z', $date);
 	}
 
@@ -443,8 +479,8 @@ class CakeTime {
  * @return string Formatted date string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function toRSS($dateString, $userOffset = null) {
-		$date = $this->fromString($dateString, $userOffset);
+	public static function toRSS($dateString, $userOffset = null) {
+		$date = self::fromString($dateString, $userOffset);
 
 		if (!is_null($userOffset)) {
 			if ($userOffset == 0) {
@@ -484,16 +520,16 @@ class CakeTime {
  * @return string Relative time string.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function timeAgoInWords($dateTime, $options = array()) {
+	public static function timeAgoInWords($dateTime, $options = array()) {
 		$userOffset = null;
 		if (is_array($options) && isset($options['userOffset'])) {
 			$userOffset = $options['userOffset'];
 		}
 		$now = time();
 		if (!is_null($userOffset)) {
-			$now = $this->convert(time(), $userOffset);
+			$now = self::convert(time(), $userOffset);
 		}
-		$inSeconds = $this->fromString($dateTime, $userOffset);
+		$inSeconds = self::fromString($dateTime, $userOffset);
 		$backwards = ($inSeconds > $now);
 
 		$format = 'j/n/y';
@@ -599,7 +635,7 @@ class CakeTime {
 		$relativeDate = '';
 		$diff = $futureTime - $pastTime;
 
-		if ($diff > abs($now - $this->fromString($end))) {
+		if ($diff > abs($now - self::fromString($end))) {
 			$relativeDate = __d('cake', 'on %s', date($format, $inSeconds));
 		} else {
 			if ($years > 0) {
@@ -650,14 +686,14 @@ class CakeTime {
  * @return boolean
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#testing-time
  */
-	public function wasWithinLast($timeInterval, $dateString, $userOffset = null) {
+	public static function wasWithinLast($timeInterval, $dateString, $userOffset = null) {
 		$tmp = str_replace(' ', '', $timeInterval);
 		if (is_numeric($tmp)) {
 			$timeInterval = $tmp . ' ' . __d('cake', 'days');
 		}
 
-		$date = $this->fromString($dateString, $userOffset);
-		$interval = $this->fromString('-' . $timeInterval);
+		$date = self::fromString($dateString, $userOffset);
+		$interval = self::fromString('-' . $timeInterval);
 
 		if ($date >= $interval && $date <= time()) {
 			return true;
@@ -673,9 +709,9 @@ class CakeTime {
  * @return integer UNIX timestamp
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function gmt($string = null) {
+	public static function gmt($string = null) {
 		if ($string != null) {
-			$string = $this->fromString($string);
+			$string = self::fromString($string);
 		} else {
 			$string = time();
 		}
@@ -701,13 +737,13 @@ class CakeTime {
  * @return string Formatted date string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function format($format, $date = null, $invalid = false, $userOffset = null) {
-		$time = $this->fromString($date, $userOffset);
-		$_time = $this->fromString($format, $userOffset);
+	public static function format($format, $date = null, $invalid = false, $userOffset = null) {
+		$time = self::fromString($date, $userOffset);
+		$_time = self::fromString($format, $userOffset);
 
 		if (is_numeric($_time) && $time === false) {
 			$format = $date;
-			return $this->i18nFormat($_time, $format, $invalid, $userOffset);
+			return self::i18nFormat($_time, $format, $invalid, $userOffset);
 		}
 		if ($time === false && $invalid !== false) {
 			return $invalid;
@@ -726,16 +762,16 @@ class CakeTime {
  * @return string Formatted and translated date string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#formatting
  */
-	public function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) {
-		$date = $this->fromString($date, $userOffset);
+	public static function i18nFormat($date, $format = null, $invalid = false, $userOffset = null) {
+		$date = self::fromString($date, $userOffset);
 		if ($date === false && $invalid !== false) {
 			return $invalid;
 		}
 		if (empty($format)) {
 			$format = '%x';
 		}
-		$format = $this->convertSpecifiers($format, $date);
-		return $this->_strftime($format, $date);
+		$format = self::convertSpecifiers($format, $date);
+		return self::_strftime($format, $date);
 	}
 
 /**
@@ -747,7 +783,7 @@ class CakeTime {
  * @param int $date Timestamp to format.
  * @return string formatted string with correct encoding.
  */
-	protected function _strftime($format, $date) {
+	protected static function _strftime($format, $date) {
 		$format = strftime($format, $date);
 		$encoding = Configure::read('App.encoding');
 

+ 6 - 6
lib/Cake/Utility/String.php

@@ -368,7 +368,7 @@ class String {
  * @return string The highlighted text
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::highlight
  */
-	public function highlight($text, $phrase, $options = array()) {
+	public static function highlight($text, $phrase, $options = array()) {
 		if (empty($phrase)) {
 			return $text;
 		}
@@ -412,7 +412,7 @@ class String {
  * @return string The text without links
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::stripLinks
  */
-	public function stripLinks($text) {
+	public static function stripLinks($text) {
 		return preg_replace('|<a\s+[^>]+>|im', '', preg_replace('|<\/a>|im', '', $text));
 	}
 
@@ -434,7 +434,7 @@ class String {
  * @return string Trimmed string.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::truncate
  */
-	public function truncate($text, $length = 100, $options = array()) {
+	public static function truncate($text, $length = 100, $options = array()) {
 		$default = array(
 			'ending' => '...', 'exact' => true, 'html' => false
 		);
@@ -550,9 +550,9 @@ class String {
  * @return string Modified string
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::excerpt
  */
-	public function excerpt($text, $phrase, $radius = 100, $ending = '...') {
+	public static function excerpt($text, $phrase, $radius = 100, $ending = '...') {
 		if (empty($text) or empty($phrase)) {
-			return $this->truncate($text, $radius * 2, array('ending' => $ending));
+			return self::truncate($text, $radius * 2, array('ending' => $ending));
 		}
 
 		$append = $prepend = $ending;
@@ -592,7 +592,7 @@ class String {
  * @return string The glued together string.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
  */
-	public function toList($list, $and = 'and', $separator = ', ') {
+	public static function toList($list, $and = 'and', $separator = ', ') {
 		if (count($list) > 1) {
 			return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list);
 		} else {

+ 9 - 2
lib/Cake/View/Helper/NumberHelper.php

@@ -43,14 +43,21 @@ class NumberHelper extends AppHelper {
 	 * @param array $settings Configuration settings for the helper
 	 */
 	function __construct(View $View, $settings = array()) {
+		$settings = Set::merge(array('engine' => 'CakeNumber'), $settings);
 		parent::__construct($View, $settings);
-		$this->_CakeNumber = new CakeNumber();
+		$engineClass = $settings['engine'];
+		App::uses($engineClass, 'Utility');
+		if (class_exists($engineClass)) {
+			$this->_CakeNumber = new $engineClass($settings);
+		} else {
+			throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+		}
 	}
 
 	/**
 	 * Call methods from CakeNumber utility class
 	 */
-	function __call($method, $params) {
+	public function __call($method, $params) {
 		return call_user_func_array(array($this->_CakeNumber, $method), $params);
 	}
 

+ 8 - 1
lib/Cake/View/Helper/TextHelper.php

@@ -60,8 +60,15 @@ class TextHelper extends AppHelper {
  * @param array $settings Settings array Settings array
  */
 	public function __construct(View $View, $settings = array()) {
+		$settings = Set::merge(array('engine' => 'String'), $settings);
 		parent::__construct($View, $settings);
-		$this->_String = new String($settings);
+		$engineClass = $settings['engine'];
+		App::uses($engineClass, 'Utility');
+		if (class_exists($engineClass)) {
+			$this->_String = new $engineClass($settings);
+		} else {
+			throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+		}
 	}
 
 	/**

+ 12 - 3
lib/Cake/View/Helper/TimeHelper.php

@@ -44,8 +44,15 @@ class TimeHelper extends AppHelper {
  * @param array $settings Settings array Settings array
  */
 	public function __construct(View $View, $settings = array()) {
+		$settings = Set::merge(array('engine' => 'CakeTime'), $settings);
 		parent::__construct($View, $settings);
-		$this->_CakeTime = new CakeTime($settings);
+		$engineClass = $settings['engine'];
+		App::uses($engineClass, 'Utility');
+		if (class_exists($engineClass)) {
+			$this->_CakeTime = new $engineClass($settings);
+		} else {
+			throw new CakeException(__d('cake_dev', '%s could not be found', $engineClass));
+		}
 	}
 
 /**
@@ -58,9 +65,11 @@ class TimeHelper extends AppHelper {
 	public function __set($name, $value) {
 		switch ($name) {
 			case 'niceFormat':
-				$this->_CakeTime->{$name} = $value; break;
+				$this->_CakeTime->{$name} = $value;
+			break;
 			default:
-				$this->{$name} = $value; break;
+				$this->{$name} = $value;
+			break;
 		}
 	}