Browse Source

Merge branch 'master' into 2.3

Conflicts:
	lib/Cake/Event/CakeEventManager.php
	lib/Cake/VERSION.txt
	lib/Cake/View/ViewBlock.php
mark_story 13 years ago
parent
commit
1aea9ac0c9

+ 2 - 2
lib/Cake/Console/Templates/skel/Config/bootstrap.php

@@ -98,11 +98,11 @@ Configure::write('Dispatcher.filters', array(
 App::uses('CakeLog', 'Log');
 CakeLog::config('debug', array(
 	'engine' => 'FileLog',
-	'scopes' => array('notice', 'info', 'debug'),
+	'types' => array('notice', 'info', 'debug'),
 	'file' => 'debug',
 ));
 CakeLog::config('error', array(
 	'engine' => 'FileLog',
-	'scopes' => array('warning', 'error', 'critical', 'alert', 'emergency'),
+	'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
 	'file' => 'error',
 ));

+ 1 - 1
lib/Cake/Model/Behavior/TreeBehavior.php

@@ -179,7 +179,7 @@ class TreeBehavior extends ModelBehavior {
 		extract($this->settings[$Model->alias]);
 
 		$this->_addToWhitelist($Model, array($left, $right));
-		if (!$Model->id) {
+		if (!$Model->id || !$Model->exists()) {
 			if (array_key_exists($parent, $Model->data[$Model->alias]) && $Model->data[$Model->alias][$parent]) {
 				$parentNode = $Model->find('first', array(
 					'conditions' => array($scope, $Model->escapeField() => $Model->data[$Model->alias][$parent]),

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

@@ -921,14 +921,14 @@ class DboSource extends DataSource {
 		$this->_queriesCnt++;
 		$this->_queriesTime += $this->took;
 		$this->_queriesLog[] = array(
-			'query'		=> $sql,
-			'params'	=> $params,
-			'affected'	=> $this->affected,
-			'numRows'	=> $this->numRows,
-			'took'		=> $this->took
+			'query' => $sql,
+			'params' => $params,
+			'affected' => $this->affected,
+			'numRows' => $this->numRows,
+			'took' => $this->took
 		);
 		if (count($this->_queriesLog) > $this->_queriesLogMax) {
-			array_pop($this->_queriesLog);
+			array_shift($this->_queriesLog);
 		}
 	}
 

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

@@ -1093,7 +1093,7 @@ class Model extends Object implements CakeEventListener {
 	}
 
 /**
- * Sets a custom table for your controller class. Used by your controller to select a database table.
+ * Sets a custom table for your model class. Used by your controller to select a database table.
  *
  * @param string $tableName Name of the custom table
  * @throws MissingTableException when database table $tableName is not found on data source
@@ -2760,8 +2760,8 @@ class Model extends Object implements CakeEventListener {
 		} elseif ($state === 'after') {
 			foreach (array(0, $this->alias) as $key) {
 				if (isset($results[0][$key]['count'])) {
-					if (($count = count($results)) > 1) {
-						return $count;
+					if ($query['group']) {
+						return count($results);
 					} else {
 						return intval($results[0][$key]['count']);
 					}

+ 1 - 1
lib/Cake/Model/Validator/CakeValidationSet.php

@@ -280,7 +280,7 @@ class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable {
 				$message = __d($this->_validationDomain, $name);
 			}
 		} else {
-			$message = __d('cake_dev', 'This field cannot be left blank');
+			$message = __d('cake', 'This field cannot be left blank');
 		}
 
 		return $message;

+ 4 - 2
lib/Cake/Network/CakeRequest.php

@@ -229,8 +229,10 @@ class CakeRequest implements ArrayAccess {
 	protected function _url() {
 		if (!empty($_SERVER['PATH_INFO'])) {
 			return $_SERVER['PATH_INFO'];
-		} elseif (isset($_SERVER['REQUEST_URI'])) {
+		} elseif (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '://') === false) {
 			$uri = $_SERVER['REQUEST_URI'];
+		} elseif (isset($_SERVER['REQUEST_URI'])) {
+			$uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL));
 		} elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) {
 			$uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);
 		} elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
@@ -319,7 +321,7 @@ class CakeRequest implements ArrayAccess {
 	protected function _processFiles() {
 		if (isset($_FILES) && is_array($_FILES)) {
 			foreach ($_FILES as $name => $data) {
-				if ($name != 'data') {
+				if ($name !== 'data') {
 					$this->params['form'][$name] = $data;
 				}
 			}

+ 1 - 1
lib/Cake/Routing/Router.php

@@ -651,7 +651,7 @@ class Router {
  * @return array Parameter information
  */
 	public static function getParams($current = false) {
-		if ($current) {
+		if ($current && self::$_requests) {
 			return self::$_requests[count(self::$_requests) - 1]->params;
 		}
 		if (isset(self::$_requests[0])) {

+ 16 - 6
lib/Cake/Test/Case/Event/CakeEventManagerTest.php

@@ -234,6 +234,10 @@ class CakeEventManagerTest extends CakeTestCase {
  * @return void
  */
 	public function testDispatchReturnValue() {
+		$this->skipIf(
+			version_compare(PHPUnit_Runner_Version::VERSION, '3.7', '<'),
+			'These tests fail in PHPUnit 3.6'
+		);
 		$manager = new CakeEventManager;
 		$listener = $this->getMock('CakeEventTestListener');
 		$anotherListener = $this->getMock('CakeEventTestListener');
@@ -241,11 +245,12 @@ class CakeEventManagerTest extends CakeTestCase {
 		$manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
 		$event = new CakeEvent('fake.event');
 
-		$firstStep = clone $event;
 		$listener->expects($this->at(0))->method('listenerFunction')
-			->with($firstStep)
+			->with($event)
 			->will($this->returnValue('something special'));
-		$anotherListener->expects($this->at(0))->method('listenerFunction')->with($event);
+		$anotherListener->expects($this->at(0))
+			->method('listenerFunction')
+			->with($event);
 		$manager->dispatch($event);
 		$this->assertEquals('something special', $event->result);
 	}
@@ -256,6 +261,11 @@ class CakeEventManagerTest extends CakeTestCase {
  * @return void
  */
 	public function testDispatchFalseStopsEvent() {
+		$this->skipIf(
+			version_compare(PHPUnit_Runner_Version::id(), '3.7', '<'),
+			'These tests fail in PHPUnit 3.6'
+		);
+
 		$manager = new CakeEventManager;
 		$listener = $this->getMock('CakeEventTestListener');
 		$anotherListener = $this->getMock('CakeEventTestListener');
@@ -263,11 +273,11 @@ class CakeEventManagerTest extends CakeTestCase {
 		$manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event');
 		$event = new CakeEvent('fake.event');
 
-		$originalEvent = clone $event;
 		$listener->expects($this->at(0))->method('listenerFunction')
-			->with($originalEvent)
+			->with($event)
 			->will($this->returnValue(false));
-		$anotherListener->expects($this->never())->method('listenerFunction');
+		$anotherListener->expects($this->never())
+			->method('listenerFunction');
 		$manager->dispatch($event);
 		$this->assertTrue($event->isStopped());
 	}

+ 30 - 2
lib/Cake/Test/Case/Model/Behavior/TreeBehaviorNumberTest.php

@@ -355,8 +355,6 @@ class TreeBehaviorNumberTest extends CakeTestCase {
 		$this->assertSame($expected, $result);
 
 		$laterCount = $this->Tree->find('count');
-
-		$laterCount = $this->Tree->find('count');
 		$this->assertEquals($initialCount + 1, $laterCount);
 
 		$children = $this->Tree->children($data[$modelClass]['id'], true, array('name'));
@@ -370,6 +368,36 @@ class TreeBehaviorNumberTest extends CakeTestCase {
 	}
 
 /**
+ * testAddWithPreSpecifiedId method
+ *
+ * @return void
+ */
+	public function testAddWithPreSpecifiedId() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+
+		$data = $this->Tree->find('first', array(
+			'fields' => array('id'),
+			'conditions' => array($modelClass . '.name' => '1.1')
+		));
+
+		$this->Tree->create();
+		$result = $this->Tree->save(array($modelClass => array(
+			'id' => 100,
+			'name' => 'testAddMiddle',
+			$parentField => $data[$modelClass]['id'])
+		));
+		$expected = array_merge(
+			array($modelClass => array('id' => 100, 'name' => 'testAddMiddle', $parentField => '2')),
+			$result
+		);
+		$this->assertSame($expected, $result);
+
+		$this->assertTrue($this->Tree->verify());
+	}
+
+/**
  * testAddInvalid method
  *
  * @return void

+ 32 - 0
lib/Cake/Test/Case/Model/Behavior/TreeBehaviorUuidTest.php

@@ -21,6 +21,7 @@
 
 App::uses('Model', 'Model');
 App::uses('AppModel', 'Model');
+App::uses('String', 'Utility');
 require_once dirname(dirname(__FILE__)) . DS . 'models.php';
 
 /**
@@ -57,6 +58,37 @@ class TreeBehaviorUuidTest extends CakeTestCase {
 	public $fixtures = array('core.uuid_tree');
 
 /**
+ * testAddWithPreSpecifiedId method
+ *
+ * @return void
+ */
+	public function testAddWithPreSpecifiedId() {
+		extract($this->settings);
+		$this->Tree = new $modelClass();
+		$this->Tree->initialize(2, 2);
+
+		$data = $this->Tree->find('first', array(
+			'fields' => array('id'),
+			'conditions' => array($modelClass . '.name' => '1.1')
+		));
+
+		$id = String::uuid();
+		$this->Tree->create();
+		$result = $this->Tree->save(array($modelClass => array(
+			'id' => $id,
+			'name' => 'testAddMiddle',
+			$parentField => $data[$modelClass]['id'])
+		));
+		$expected = array_merge(
+			array($modelClass => array('id' => $id, 'name' => 'testAddMiddle', $parentField => '2')),
+			$result
+		);
+		$this->assertSame($expected, $result);
+
+		$this->assertTrue($this->Tree->verify());
+	}
+
+/**
  * testMovePromote method
  *
  * @return void

+ 12 - 1
lib/Cake/Test/Case/Model/ModelReadTest.php

@@ -6860,6 +6860,17 @@ class ModelReadTest extends BaseModelTest {
 		));
 		$result = $Article->find('count', array('group' => array('Article.user_id')));
 		$this->assertEquals($expected, $result);
+
+		$expected = count($Article->find('all', array(
+			'fields' => array('Article.user_id'),
+			'conditions' => array('Article.user_id' => 1),
+			'group' => 'Article.user_id')
+		));
+		$result = $Article->find('count', array(
+			'conditions' => array('Article.user_id' => 1),
+			'group' => array('Article.user_id'),
+		));
+		$this->assertEquals($expected, $result);
 	}
 
 /**
@@ -6886,7 +6897,7 @@ class ModelReadTest extends BaseModelTest {
 		$this->skipIf($this->db instanceof Sqlite, 'SELECT COUNT(DISTINCT field) is not compatible with SQLite.');
 		$this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
 
-		$this->loadFixtures('Project');
+		$this->loadFixtures('Project', 'Thread');
 		$TestModel = new Project();
 		$TestModel->create(array('name' => 'project')) && $TestModel->save();
 		$TestModel->create(array('name' => 'project')) && $TestModel->save();

+ 42 - 0
lib/Cake/Test/Case/Network/CakeRequestTest.php

@@ -588,6 +588,24 @@ class CakeRequestTest extends CakeTestCase {
 	}
 
 /**
+ * Test that files in the 0th index work.
+ */
+	public function testFilesZeroithIndex() {
+		$_FILES = array(
+			0 => array(
+				'name' => 'cake_sqlserver_patch.patch',
+				'type' => 'text/plain',
+				'tmp_name' => '/private/var/tmp/phpy05Ywj',
+				'error' => 0,
+				'size' => 6271,
+			),
+		);
+
+		$request = new CakeRequest('some/path');
+		$this->assertEquals($_FILES, $request->params['form']);
+	}
+
+/**
  * test method overrides coming in from POST data.
  *
  * @return void
@@ -1629,6 +1647,30 @@ class CakeRequestTest extends CakeTestCase {
 				),
 			),
 			array(
+				'Apache - w/rewrite, document root set above top level cake dir, request root, absolute REQUEST_URI',
+				array(
+					'App' => array(
+						'base' => false,
+						'baseUrl' => false,
+						'dir' => 'app',
+						'webroot' => 'webroot'
+					),
+					'SERVER' => array(
+						'SERVER_NAME' => 'localhost',
+						'DOCUMENT_ROOT' => '/Library/WebServer/Documents',
+						'SCRIPT_FILENAME' => '/Library/WebServer/Documents/site/index.php',
+						'REQUEST_URI' => FULL_BASE_URL . '/site/posts/index',
+						'SCRIPT_NAME' => '/site/app/webroot/index.php',
+						'PHP_SELF' => '/site/app/webroot/index.php',
+					),
+				),
+				array(
+					'url' => 'posts/index',
+					'base' => '/site',
+					'webroot' => '/site/',
+				),
+			),
+			array(
 				'Nginx - w/rewrite, document root set to webroot, request root, no PATH_INFO',
 				array(
 					'App' => array(

+ 69 - 43
lib/Cake/Test/Case/View/Helper/TextHelperTest.php

@@ -166,65 +166,91 @@ class TextHelperTest extends CakeTestCase {
 	}
 
 /**
+ * Data provider for autoLinking
+ */
+	public static function autoLinkProvider() {
+		return array(
+			array(
+				'This is a test text',
+				'This is a test text',
+			),
+			array(
+				'This is a test that includes (www.cakephp.org)',
+				'This is a test that includes (<a href="http://www.cakephp.org">www.cakephp.org</a>)',
+			),
+			array(
+				'This is a test that includes www.cakephp.org:8080',
+				'This is a test that includes <a href="http://www.cakephp.org:8080">www.cakephp.org:8080</a>',
+			),
+			array(
+				'This is a test that includes http://de.wikipedia.org/wiki/Kanton_(Schweiz)#fragment',
+				'This is a test that includes <a href="http://de.wikipedia.org/wiki/Kanton_(Schweiz)#fragment">http://de.wikipedia.org/wiki/Kanton_(Schweiz)#fragment</a>',
+			),
+			array(
+				'This is a test that includes www.wikipedia.org/wiki/Kanton_(Schweiz)#fragment',
+				'This is a test that includes <a href="http://www.wikipedia.org/wiki/Kanton_(Schweiz)#fragment">www.wikipedia.org/wiki/Kanton_(Schweiz)#fragment</a>',
+			),
+			array(
+				'This is a test that includes http://example.com/test.php?foo=bar text',
+				'This is a test that includes <a href="http://example.com/test.php?foo=bar">http://example.com/test.php?foo=bar</a> text',
+			),
+			array(
+				'This is a test that includes www.example.com/test.php?foo=bar text',
+				'This is a test that includes <a href="http://www.example.com/test.php?foo=bar">www.example.com/test.php?foo=bar</a> text',
+			),
+			array(
+				'Text with a partial www.cakephp.org URL',
+				'Text with a partial <a href="http://www.cakephp.org">www.cakephp.org</a> URL',
+			),
+			array(
+				'Text with a partial WWW.cakephp.org URL',
+				'Text with a partial <a href="http://WWW.cakephp.org">WWW.cakephp.org</a> URL',
+			),
+			array(
+				'Text with a partial WWW.cakephp.org &copy, URL',
+				'Text with a partial <a href="http://WWW.cakephp.org">WWW.cakephp.org</a> &amp;copy, URL',
+			),
+			array(
+				'Text with a url www.cot.ag/cuIb2Q and more',
+				'Text with a url <a href="http://www.cot.ag/cuIb2Q">www.cot.ag/cuIb2Q</a> and more',
+			),
+			array(
+				'Text with a url http://www.does--not--work.com and more',
+				'Text with a url <a href="http://www.does--not--work.com">http://www.does--not--work.com</a> and more',
+			),
+			array(
+				'Text with a url http://www.not--work.com and more',
+				'Text with a url <a href="http://www.not--work.com">http://www.not--work.com</a> and more',
+			),
+		);
+	}
+
+/**
  * testAutoLinkUrls method
  *
+ * @dataProvider autoLinkProvider
  * @return void
  */
-	public function testAutoLinkUrls() {
-		$text = 'This is a test text';
-		$expected = 'This is a test text';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
-
-		$text = 'This is a test that includes (www.cakephp.org)';
-		$expected = 'This is a test that includes (<a href="http://www.cakephp.org">www.cakephp.org</a>)';
+	public function testAutoLinkUrls($text, $expected) {
 		$result = $this->Text->autoLinkUrls($text);
 		$this->assertEquals($expected, $result);
+	}
 
-		$text = 'This is a test that includes http://de.wikipedia.org/wiki/Kanton_(Schweiz)#fragment';
-		$expected = 'This is a test that includes <a href="http://de.wikipedia.org/wiki/Kanton_(Schweiz)#fragment">http://de.wikipedia.org/wiki/Kanton_(Schweiz)#fragment</a>';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
-
-		$text = 'This is a test that includes www.wikipedia.org/wiki/Kanton_(Schweiz)#fragment';
-		$expected = 'This is a test that includes <a href="http://www.wikipedia.org/wiki/Kanton_(Schweiz)#fragment">www.wikipedia.org/wiki/Kanton_(Schweiz)#fragment</a>';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
-
-		$text = 'Text with a partial www.cakephp.org URL';
-		$expected = 'Text with a partial <a href="http://www.cakephp.org"\s*>www.cakephp.org</a> URL';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertRegExp('#^' . $expected . '$#', $result);
-
+/**
+ * Test the options for autoLinkUrls
+ *
+ * @return void
+ */
+	public function testAutoLinkUrlsOptions() {
 		$text = 'Text with a partial www.cakephp.org URL';
 		$expected = 'Text with a partial <a href="http://www.cakephp.org" \s*class="link">www.cakephp.org</a> URL';
 		$result = $this->Text->autoLinkUrls($text, array('class' => 'link'));
 		$this->assertRegExp('#^' . $expected . '$#', $result);
 
-		$text = 'Text with a partial WWW.cakephp.org URL';
-		$expected = 'Text with a partial <a href="http://WWW.cakephp.org"\s*>WWW.cakephp.org</a> URL';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertRegExp('#^' . $expected . '$#', $result);
-
 		$text = 'Text with a partial WWW.cakephp.org &copy; URL';
 		$expected = 'Text with a partial <a href="http://WWW.cakephp.org"\s*>WWW.cakephp.org</a> &copy; URL';
 		$result = $this->Text->autoLinkUrls($text, array('escape' => false));
 		$this->assertRegExp('#^' . $expected . '$#', $result);
-
-		$text = 'Text with a url www.cot.ag/cuIb2Q and more';
-		$expected = 'Text with a url <a href="http://www.cot.ag/cuIb2Q">www.cot.ag/cuIb2Q</a> and more';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
-
-		$text = 'Text with a url http://www.does--not--work.com and more';
-		$expected = 'Text with a url <a href="http://www.does--not--work.com">http://www.does--not--work.com</a> and more';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
-
-		$text = 'Text with a url http://www.not--work.com and more';
-		$expected = 'Text with a url <a href="http://www.not--work.com">http://www.not--work.com</a> and more';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
 	}
 
 /**

+ 2 - 0
lib/Cake/TestSuite/CakeTestRunner.php

@@ -17,6 +17,8 @@
  */
 require_once 'PHPUnit/TextUI/TestRunner.php';
 
+App::uses('CakeFixtureManager', 'TestSuite/Fixture');
+
 /**
  * A custom test runner for Cake's use of PHPUnit.
  *

+ 2 - 1
lib/Cake/View/Helper/FormHelper.php

@@ -299,8 +299,9 @@ class FormHelper extends AppHelper {
  *   can be overridden when calling input()
  * - `encoding` Set the accept-charset encoding for the form.  Defaults to `Configure::read('App.encoding')`
  *
- * @param string $model The model object which the form is being defined for.  Should
+ * @param string|array $model The model object which the form is being defined for. Should
  *   include the plugin name for plugin forms.  e.g. `ContactManager.Contact`.
+ *   If an array is passed and $options argument is empty, the array will be used as options.
  * @param array $options An array of html attributes and options.
  * @return string An formatted opening FORM tag.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#options-for-create

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

@@ -102,7 +102,7 @@ class TextHelper extends AppHelper {
 		$this->_placeholders = array();
 		$options += array('escape' => true);
 
-		$pattern = '#(?<!href="|src="|">)((?:https?|ftp|nntp)://[^\s<>()]+\.[a-z]+(?:\/[^\s]+)?)#i';
+		$pattern = '#(?<!href="|src="|">)((?:https?|ftp|nntp)://[a-z0-9.\-:]+(?:/[^\s]*)?)#i';
 		$text = preg_replace_callback(
 			$pattern,
 			array(&$this, '_insertPlaceHolder'),