Browse Source

Merge branch '1.3' into merger

Conflicts:
	cake/basics.php
	cake/console/libs/tasks/extract.php
	cake/libs/view/helpers/js.php
	cake/tests/cases/console/libs/tasks/extract.test.php
	cake/tests/cases/libs/model/datasources/dbo/dbo_mysql.test.php
	cake/tests/cases/libs/model/datasources/dbo_source.test.php
	cake/tests/test_app/views/pages/extract.ctp
	lib/Cake/Cache/Engine/MemcacheEngine.php
	lib/Cake/Model/Behavior/ContainableBehavior.php
	lib/Cake/Model/Datasource/Database/Mysql.php
	lib/Cake/Model/Datasource/DboSource.php
	lib/Cake/Model/Model.php
	lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php
	lib/Cake/Test/Case/Model/CakeSchemaTest.php
	lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php
	lib/Cake/Test/Case/View/Helper/FormHelperTest.php
	lib/Cake/Test/Case/View/Helper/TimeHelperTest.php
mark_story 14 years ago
parent
commit
6a4e7558fc

+ 4 - 1
lib/Cake/Cache/Engine/MemcacheEngine.php

@@ -89,12 +89,15 @@ class MemcacheEngine extends CacheEngine {
 
 
 /**
 /**
  * Parses the server address into the host/port.  Handles both IPv6 and IPv4
  * Parses the server address into the host/port.  Handles both IPv6 and IPv4
- * addresses
+ * addresses and Unix sockets
  *
  *
  * @param string $server The server address string.
  * @param string $server The server address string.
  * @return array Array containing host, port
  * @return array Array containing host, port
  */
  */
 	protected function _parseServerString($server) {
 	protected function _parseServerString($server) {
+		if ($server[0] == 'u') {
+			return array($server, 0);
+		}
 		if (substr($server, 0, 1) == '[') {
 		if (substr($server, 0, 1) == '[') {
 			$position = strpos($server, ']:');
 			$position = strpos($server, ']:');
 			if ($position !== false) {
 			if ($position !== false) {

+ 0 - 20
lib/Cake/Model/Behavior/ContainableBehavior.php

@@ -148,8 +148,6 @@ class ContainableBehavior extends ModelBehavior {
 					if (!empty($unbind)) {
 					if (!empty($unbind)) {
 						if (!$reset && empty($instance->__backOriginalAssociation)) {
 						if (!$reset && empty($instance->__backOriginalAssociation)) {
 							$instance->__backOriginalAssociation = $backupBindings;
 							$instance->__backOriginalAssociation = $backupBindings;
-						} else if ($reset && empty($instance->__backContainableAssociation)) {
-							$instance->__backContainableAssociation = $backupBindings;
 						}
 						}
 						$instance->unbindModel(array($type => $unbind), $reset);
 						$instance->unbindModel(array($type => $unbind), $reset);
 					}
 					}
@@ -222,24 +220,6 @@ class ContainableBehavior extends ModelBehavior {
 	}
 	}
 
 
 /**
 /**
- * Resets original associations on models that may have receive multiple,
- * subsequent unbindings.
- *
- * @param Model $Model Model on which we are resetting
- * @param array $results Results of the find operation
- * @param boolean $primary true if this is the primary model that issued the find operation, false otherwise
- * @return void
- */
-	public function afterFind($Model, $results, $primary) {
-		if (!empty($Model->__backContainableAssociation)) {
-			foreach ($Model->__backContainableAssociation as $relation => $bindings) {
-				$Model->{$relation} = $bindings;
-				unset($Model->__backContainableAssociation);
-			}
-		}
-	}
-
-/**
  * Unbinds all relations from a model except the specified ones. Calling this function without
  * Unbinds all relations from a model except the specified ones. Calling this function without
  * parameters unbinds all related models.
  * parameters unbinds all related models.
  *
  *

+ 2 - 7
lib/Cake/Model/Datasource/Database/Postgres.php

@@ -480,11 +480,7 @@ class Postgres extends DboSource {
 						case 'add':
 						case 'add':
 							foreach ($column as $field => $col) {
 							foreach ($column as $field => $col) {
 								$col['name'] = $field;
 								$col['name'] = $field;
-								$alter = 'ADD COLUMN '.$this->buildColumn($col);
-								if (isset($col['after'])) {
-									$alter .= ' AFTER '. $this->name($col['after']);
-								}
-								$colList[] = $alter;
+								$colList[] = 'ADD COLUMN '.$this->buildColumn($col);
 							}
 							}
 						break;
 						break;
 						case 'drop':
 						case 'drop':
@@ -503,8 +499,7 @@ class Postgres extends DboSource {
 								$default = isset($col['default']) ? $col['default'] : null;
 								$default = isset($col['default']) ? $col['default'] : null;
 								$nullable = isset($col['null']) ? $col['null'] : null;
 								$nullable = isset($col['null']) ? $col['null'] : null;
 								unset($col['default'], $col['null']);
 								unset($col['default'], $col['null']);
-								$colList[] = 'ALTER COLUMN '. $fieldName .' TYPE ' . str_replace($fieldName, '', $this->buildColumn($col));
-
+								$colList[] = 'ALTER COLUMN '. $fieldName .' TYPE ' . str_replace(array($fieldName, 'NOT NULL'), '', $this->buildColumn($col));
 								if (isset($nullable)) {
 								if (isset($nullable)) {
 									$nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL';
 									$nullable = ($nullable) ? 'DROP NOT NULL' : 'SET NOT NULL';
 									$colList[] = 'ALTER COLUMN '. $fieldName .'  ' . $nullable;
 									$colList[] = 'ALTER COLUMN '. $fieldName .'  ' . $nullable;

+ 3 - 3
lib/Cake/Model/Datasource/DboSource.php

@@ -328,7 +328,7 @@ class DboSource extends DataSource {
 					return 'NULL';
 					return 'NULL';
 				}
 				}
 				if (is_float($data)) {
 				if (is_float($data)) {
-					return sprintf('%F', $data);
+					return str_replace(',', '.', sprintf('%G', $data));
 				}
 				}
 				if ((is_int($data) || $data === '0') || (
 				if ((is_int($data) || $data === '0') || (
 					is_numeric($data) && strpos($data, ',') === false &&
 					is_numeric($data) && strpos($data, ',') === false &&
@@ -2381,8 +2381,8 @@ class DboSource extends DataSource {
  * @return string
  * @return string
  */
  */
 	protected function _parseKey($model, $key, $value) {
 	protected function _parseKey($model, $key, $value) {
-		$operatorMatch = '/^((' . implode(')|(', $this->_sqlOps);
-		$operatorMatch .= '\\x20)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is';
+		$operatorMatch = '/^(((' . implode(')|(', $this->_sqlOps);
+		$operatorMatch .= ')\\x20?)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is';
 		$bound = (strpos($key, '?') !== false || (is_array($value) && strpos($key, ':') !== false));
 		$bound = (strpos($key, '?') !== false || (is_array($value) && strpos($key, ':') !== false));
 
 
 		if (strpos($key, ' ') === false) {
 		if (strpos($key, ' ') === false) {

+ 2 - 0
lib/Cake/Model/Model.php

@@ -2432,6 +2432,8 @@ class Model extends Object {
  *  - If three fields are specified, they are used (in order) for key, value and group.
  *  - If three fields are specified, they are used (in order) for key, value and group.
  *  - Otherwise, first and second fields are used for key and value.
  *  - Otherwise, first and second fields are used for key and value.
  *
  *
+ *  Note: find(list) + database views have issues with MySQL 5.0. Try upgrading to MySQL 5.1 if you 
+ *  have issues with database views.
  * @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
  * @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
  * @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
  * @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
  * @return array Array of records
  * @return array Array of records

+ 11 - 0
lib/Cake/Test/Case/Cache/Engine/MemcacheEngineTest.php

@@ -165,6 +165,17 @@ class MemcacheEngineTest extends CakeTestCase {
 	}
 	}
 
 
 /**
 /**
+ * test unix sockets.
+ *
+ * @return void
+ */
+    function testParseServerStringUnix() {
+        $Memcache =& new TestMemcacheEngine();
+        $result = $Memcache->parseServerString('unix:///path/to/memcached.sock');
+        $this->assertEqual($result, array('unix:///path/to/memcached.sock', 0));
+    }
+
+/**
  * testReadAndWriteCache method
  * testReadAndWriteCache method
  *
  *
  * @return void
  * @return void

+ 17 - 1
lib/Cake/Test/Case/Model/Behavior/ContainableBehaviorTest.php

@@ -36,7 +36,8 @@ class ContainableBehaviorTest extends CakeTestCase {
 	public $fixtures = array(
 	public $fixtures = array(
 		'core.article', 'core.article_featured', 'core.article_featureds_tags',
 		'core.article', 'core.article_featured', 'core.article_featureds_tags',
 		'core.articles_tag', 'core.attachment', 'core.category',
 		'core.articles_tag', 'core.attachment', 'core.category',
-		'core.comment', 'core.featured', 'core.tag', 'core.user'
+		'core.comment', 'core.featured', 'core.tag', 'core.user',
+		'core.join_a', 'core.join_b', 'core.join_c', 'core.join_a_c', 'core.join_a_b'
 	);
 	);
 
 
 /**
 /**
@@ -3303,6 +3304,21 @@ class ContainableBehaviorTest extends CakeTestCase {
 		$this->assertEqual($expected, array_keys($result));
 		$this->assertEqual($expected, array_keys($result));
 
 
 		$this->assertTrue(empty($this->Article->hasMany['ArticlesTag']));
 		$this->assertTrue(empty($this->Article->hasMany['ArticlesTag']));
+		
+		$this->JoinA =& ClassRegistry::init('JoinA');
+		$this->JoinB =& ClassRegistry::init('JoinB');
+		$this->JoinC =& ClassRegistry::init('JoinC');
+		
+		$this->JoinA->Behaviors->attach('Containable');
+		$this->JoinB->Behaviors->attach('Containable');
+		$this->JoinC->Behaviors->attach('Containable');
+		
+		$this->JoinA->JoinB->find('all', array('contain' => array('JoinA')));
+		$this->JoinA->bindModel(array('hasOne' => array('JoinAsJoinC' => array('joinTable' => 'as_cs'))), false);
+		$result = $this->JoinA->hasOne;
+		$this->JoinA->find('all');
+		$resultAfter = $this->JoinA->hasOne;
+		$this->assertEqual($result, $resultAfter);
 	}
 	}
 
 
 /**
 /**

+ 32 - 4
lib/Cake/Test/Case/Model/Datasource/Database/MysqlTest.php

@@ -150,15 +150,34 @@ class MysqlTest extends CakeTestCase {
 		setlocale(LC_ALL, 'de_DE');
 		setlocale(LC_ALL, 'de_DE');
 
 
 		$result = $this->Dbo->value(3.141593, 'float');
 		$result = $this->Dbo->value(3.141593, 'float');
-		$this->assertEqual((string)$result, '3.141593');
+		$this->assertTrue(strpos((string)$result, ',') === false);
 
 
 		$result = $this->Dbo->value(3.141593);
 		$result = $this->Dbo->value(3.141593);
-		$this->assertEqual((string)$result, '3.141593');
+		$this->assertTrue(strpos((string)$result, ',') === false);
+
+		$result = $this->db->value(2.2E-54, 'float');
+		$this->assertEqual('2.2E-54', (string)$result);
+
+		$result = $this->db->value(2.2E-54);
+		$this->assertEqual('2.2E-54', (string)$result);
 
 
 		setlocale(LC_ALL, $restore);
 		setlocale(LC_ALL, $restore);
 	}
 	}
 
 
 /**
 /**
+ * test that scientific notations are working correctly
+ *
+ * @return void
+ */
+	function testScientificNotation() {
+		$result = $this->db->value(2.2E-54, 'float');
+		$this->assertEqual('2.2E-54', (string)$result);
+
+		$result = $this->db->value(2.2E-54);
+		$this->assertEqual('2.2E-54', (string)$result);
+	}
+
+/**
  * testTinyintCasting method
  * testTinyintCasting method
  *
  *
  *
  *
@@ -1856,6 +1875,11 @@ class MysqlTest extends CakeTestCase {
 		$result = $this->Dbo->conditions($conditions);
 		$result = $this->Dbo->conditions($conditions);
 		$expected = " WHERE `Artist`.`name` = 'JUDY AND MARY'";
 		$expected = " WHERE `Artist`.`name` = 'JUDY AND MARY'";
 		$this->assertEqual($expected, $result);
 		$this->assertEqual($expected, $result);
+
+		$conditions = array('Company.name similar to ' => 'a word');
+		$result = $this->Dbo->conditions($conditions);
+		$expected = " WHERE `Company`.`name` similar to 'a word'";
+		$this->assertEqual($result, $expected);
 	}
 	}
 
 
 /**
 /**
@@ -2006,11 +2030,11 @@ class MysqlTest extends CakeTestCase {
 		$this->assertEqual($expected, $result);
 		$this->assertEqual($expected, $result);
 
 
 		$result = $this->Dbo->conditions(array('score BETWEEN ? AND ?' => array(90.1, 95.7)));
 		$result = $this->Dbo->conditions(array('score BETWEEN ? AND ?' => array(90.1, 95.7)));
-		$expected = " WHERE `score` BETWEEN 90.100000 AND 95.700000";
+		$expected = " WHERE `score` BETWEEN 90.1 AND 95.7";
 		$this->assertEqual($expected, $result);
 		$this->assertEqual($expected, $result);
 
 
 		$result = $this->Dbo->conditions(array('Post.title' => 1.1));
 		$result = $this->Dbo->conditions(array('Post.title' => 1.1));
-		$expected = " WHERE `Post`.`title` = 1.100000";
+		$expected = " WHERE `Post`.`title` = 1.1";
 		$this->assertEqual($expected, $result);
 		$this->assertEqual($expected, $result);
 
 
 		$result = $this->Dbo->conditions(array('Post.title' => 1.1), true, true, new Post());
 		$result = $this->Dbo->conditions(array('Post.title' => 1.1), true, true, new Post());
@@ -2025,6 +2049,10 @@ class MysqlTest extends CakeTestCase {
 		$expected = " WHERE MAX(`Post`.`rating`) > '50'";
 		$expected = " WHERE MAX(`Post`.`rating`) > '50'";
 		$this->assertEqual($expected, $result);
 		$this->assertEqual($expected, $result);
 
 
+		$result = $this->Dbo->conditions(array('lower(Article.title)' =>  'secrets'));
+		$expected = " WHERE lower(`Article`.`title`) = 'secrets'";
+		$this->assertEqual($result, $expected);
+
 		$result = $this->Dbo->conditions(array('title LIKE' => '%hello'));
 		$result = $this->Dbo->conditions(array('title LIKE' => '%hello'));
 		$expected = " WHERE `title` LIKE '%hello'";
 		$expected = " WHERE `title` LIKE '%hello'";
 		$this->assertEqual($expected, $result);
 		$this->assertEqual($expected, $result);

+ 16 - 0
lib/Cake/Test/Case/Model/Datasource/Database/PostgresTest.php

@@ -656,6 +656,22 @@ class PostgresTest extends CakeTestCase {
 		$this->assertEqual($result['title']['null'], false);
 		$this->assertEqual($result['title']['null'], false);
 
 
 		$this->Dbo->query($this->Dbo->dropSchema($New));
 		$this->Dbo->query($this->Dbo->dropSchema($New));
+
+		$New = new CakeSchema(array(
+			'connection' => 'test_suite',
+			'name' => 'AlterPosts',
+			'alter_posts' => array(
+				'id' => array('type' => 'string', 'length' => 36, 'key' => 'primary'),
+				'author_id' => array('type' => 'integer', 'null' => false),
+				'title' => array('type' => 'string', 'null' => true),
+				'body' => array('type' => 'text'),
+				'published' => array('type' => 'string', 'length' => 1, 'default' => 'N'),
+				'created' => array('type' => 'datetime'),
+				'updated' => array('type' => 'datetime'),
+			)
+		));
+		$result = $this->Dbo->alterSchema($New->compare($Old), 'alter_posts');
+		$this->assertNoPattern('/varchar\(36\) NOT NULL/i', $result);
 	}
 	}
 
 
 /**
 /**

+ 10 - 0
lib/Cake/Test/Case/View/Helper/TimeHelperTest.php

@@ -396,6 +396,16 @@ class TimeHelperTest extends CakeTestCase {
  */
  */
 	public function testToRss() {
 	public function testToRss() {
 		$this->assertEqual(date('r'), $this->Time->toRss(time()));
 		$this->assertEqual(date('r'), $this->Time->toRss(time()));
+
+		if (!$this->skipIf(!class_exists('DateTimeZone'), '%s DateTimeZone class not available.')) {
+			$timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
+			foreach($timezones as $timezone) {
+				$yourTimezone = new DateTimeZone($timezone);
+				$yourTime = new DateTime('now', $yourTimezone);
+				$userOffset = $yourTimezone->getOffset($yourTime) / HOUR;
+				$this->assertEqual($yourTime->format('r'), $this->Time->toRss(time(), $userOffset));	
+			}	
+		}
 	}
 	}
 
 
 /**
 /**

+ 2 - 2
lib/Cake/View/Helper/JsHelper.php

@@ -74,7 +74,7 @@ class JsHelper extends AppHelper {
  *
  *
  * @var string
  * @var string
  */
  */
-	public $setVariable = APP_DIR;
+	public $setVariable = 'app';
 
 
 /**
 /**
  * Constructor - determines engine helper
  * Constructor - determines engine helper
@@ -419,4 +419,4 @@ class JsHelper extends AppHelper {
 		}
 		}
 		return array($options, $htmlOptions);
 		return array($options, $htmlOptions);
 	}
 	}
-}
+}

+ 11 - 0
lib/Cake/View/Helper/TimeHelper.php

@@ -454,6 +454,17 @@ class TimeHelper extends AppHelper {
  */
  */
 	public function toRSS($dateString, $userOffset = null) {
 	public function toRSS($dateString, $userOffset = null) {
 		$date = $this->fromString($dateString, $userOffset);
 		$date = $this->fromString($dateString, $userOffset);
+
+		if(!is_null($userOffset)) {
+			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);
 		return date("r", $date);
 	}
 	}