Browse Source

Merge remote-tracking branch 'origin/2.6' into 3.0

Conflicts:
	app/Console/cake.php
	lib/Cake/Console/ShellDispatcher.php
	lib/Cake/Console/Templates/skel/Console/cake.php
	lib/Cake/Console/cake.php
	lib/Cake/Controller/Scaffold.php
	lib/Cake/TestSuite/Fixture/CakeFixtureManager.php
	lib/Cake/View/Errors/missing_layout.ctp
	lib/Cake/View/Errors/missing_view.ctp
	src/Auth/BasicAuthenticate.php
	src/Utility/String.php
	src/View/View.php
mark_story 11 years ago
parent
commit
bfb407cb04

+ 3 - 3
src/Auth/BasicAuthenticate.php

@@ -46,9 +46,9 @@ use Cake\Network\Response;
  * by this authentication provider which triggers the login dialog in the browser/client.
  *
  * You may also want to use `$this->Auth->unauthorizedRedirect = false;`.
- * By default unauthorized user is redirected to the referrer URL or
- * AuthComponent::$loginAction or '/'. If unauthorizedRedirect is set to false a
- * ForbiddenException exception is thrown instead of redirecting.
+ * By default, unauthorized users are redirected to the referrer URL,
+ * `AuthComponent::$loginAction`, or '/'. If unauthorizedRedirect is set to
+ * false, a ForbiddenException exception is thrown instead of redirecting.
  */
 class BasicAuthenticate extends BaseAuthenticate {
 

+ 20 - 0
src/I18n/I18n.php

@@ -658,6 +658,26 @@ class I18n {
 	}
 
 /**
+ * Puts the parameters in raw translated strings
+ *
+ * @param string $translated The raw translated string
+ * @param array $args The arguments to put in the translation
+ * @return string Translated string with arguments
+ */
+	public static function insertArgs($translated, array $args) {
+		if (empty($args)) {
+			return $translated;
+		}
+
+		if (is_array($args[0])) {
+			$args = $args[0];
+		}
+
+		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
+		return vsprintf($translated, $args);
+	}
+
+/**
  * Auxiliary function to parse a symbol from a locale definition file
  *
  * @param string $string Symbol to be parsed

+ 16 - 3
src/Template/Error/missing_layout.ctp

@@ -19,10 +19,23 @@
 	<strong>Error: </strong>
 	<?= sprintf('The layout file <em>%s</em> can not be found or does not exist.', h($file)); ?>
 </p>
-<p class="error">
-	<strong>Error: </strong>
-	<?= sprintf('Confirm you have created the file: <em>%s</em>', h($file)); ?>
+
+<p>
+	<?php echo __d('cake_dev', 'Confirm you have created the file: %s', h($file)); ?>
+	in one of the following paths:
 </p>
+<ul>
+<?php
+	$paths = $this->_paths($this->plugin);
+	foreach ($paths as $path):
+		if (strpos($path, CORE_PATH) !== false) {
+			continue;
+		}
+		echo sprintf('<li>%s%s</li>', h($path), h($file));
+	endforeach;
+?>
+</ul>
+
 <p class="notice">
 	<strong>Notice: </strong>
 	<?= sprintf('If you want to customize this error message, create %s', APP_DIR . DS . 'Template' . DS . 'Error' . DS . 'missing_layout.ctp'); ?>

+ 16 - 3
src/Template/Error/missing_view.ctp

@@ -20,10 +20,23 @@ use Cake\Utility\Inflector;
 	<strong>Error: </strong>
 	<?= sprintf('The view for <em>%sController::%s()</em> was not found.', h(Inflector::camelize($this->request->controller)), h($this->request->action)); ?>
 </p>
-<p class="error">
-	<strong>Error: </strong>
-	<?= sprintf('Confirm you have created the file: %s', h($file)); ?>
+
+<p>
+	<?php echo __d('cake_dev', 'Confirm you have created the file: %s', h($file)); ?>
+	in one of the following paths:
 </p>
+<ul>
+<?php
+	$paths = $this->_paths($this->plugin);
+	foreach ($paths as $path):
+		if (strpos($path, CORE_PATH) !== false) {
+			continue;
+		}
+		echo sprintf('<li>%s%s</li>', h($path), h($file));
+	endforeach;
+?>
+</ul>
+
 <p class="notice">
 	<strong>Notice: </strong>
 	<?= sprintf('If you want to customize this error message, create %s', APP_DIR . DS . 'Template' . DS . 'Error' . DS . 'missing_view.ctp'); ?>

+ 6 - 2
src/TestSuite/Fixture/FixtureManager.php

@@ -248,7 +248,9 @@ class FixtureManager {
 						if (!in_array($db->configName(), (array)$fixture->created)) {
 							$this->_setupTable($fixture, $db, $test->dropTables);
 						}
-						$fixture->truncate($db);
+						if (!$test->dropTables) {
+							$fixture->truncate($db);
+						}
 						$fixture->insert($db);
 					}
 				});
@@ -299,7 +301,9 @@ class FixtureManager {
 			if (!in_array($db->configName(), (array)$fixture->created)) {
 				$this->_setupTable($fixture, $db, $dropTables);
 			}
-			$fixture->truncate($db);
+			if (!$dropTables) {
+				$fixture->truncate($db);
+			}
 			$fixture->insert($db);
 		} else {
 			throw new \UnexpectedValueException(sprintf('Referenced fixture class %s not found', $name));

+ 4 - 1
src/Utility/Hash.php

@@ -212,7 +212,10 @@ class Hash {
 			if (isset($data[$attr])) {
 				$prop = $data[$attr];
 			}
-			if ($prop === true || $prop === false) {
+			$isBool = is_bool($prop);
+			if ($isBool && is_numeric($val)) {
+				$prop = $prop ? '1' : '0';
+			} elseif ($isBool) {
 				$prop = $prop ? 'true' : 'false';
 			}
 

+ 1 - 1
src/Utility/Inflector.php

@@ -163,7 +163,7 @@ class Inflector {
 		'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media',
 		'metadata', 'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
 		'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
-		'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
+		'proceedings', 'rabies', 'research', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
 		'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'swine', 'testes',
 		'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting', 'wildebeest',
 		'Yengeese'

+ 8 - 5
src/Utility/String.php

@@ -660,15 +660,18 @@ class String {
 	}
 
 /**
- * Creates a comma separated list where the last two items are joined with 'and', forming natural English
+ * Creates a comma separated list where the last two items are joined with 'and', forming natural language.
  *
- * @param array $list The list to be joined
- * @param string $and The word used to join the last and second last items together with. Defaults to 'and'
- * @param string $separator The separator used to join all the other items together. Defaults to ', '
+ * @param array $list The list to be joined.
+ * @param string $and The word used to join the last and second last items together with. Defaults to 'and'.
+ * @param string $separator The separator used to join all the other items together. Defaults to ', '.
  * @return string The glued together string.
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
  */
-	public static function toList(array $list, $and = 'and', $separator = ', ') {
+	public static function toList(array $list, $and = null, $separator = ', ') {
+		if ($and === null) {
+			$and = __d('cake', 'and');
+		}
 		if (count($list) > 1) {
 			return implode($separator, array_slice($list, null, -1)) . ' ' . $and . ' ' . array_pop($list);
 		}

+ 6 - 6
src/View/Helper/TextHelper.php

@@ -197,7 +197,7 @@ class TextHelper extends Helper {
 
 		$atom = '[\p{L}0-9!#$%&\'*+\/=?^_`{|}~-]';
 		$text = preg_replace_callback(
-			'/(?<=\s|^|\()(' . $atom . '*(?:\.' . $atom . '+)*@[\p{L}0-9-]+(?:\.[\p{L}0-9-]+)+)/ui',
+			'/(?<=\s|^|\(|\>|\;)(' . $atom . '*(?:\.' . $atom . '+)*@[\p{L}0-9-]+(?:\.[\p{L}0-9-]+)+)/ui',
 			array(&$this, '_insertPlaceholder'),
 			$text
 		);
@@ -336,16 +336,16 @@ class TextHelper extends Helper {
 	}
 
 /**
- * Creates a comma separated list where the last two items are joined with 'and', forming natural English
+ * Creates a comma separated list where the last two items are joined with 'and', forming natural language.
  *
- * @param array $list The list to be joined
- * @param string $and The word used to join the last and second last items together with. Defaults to 'and'
- * @param string $separator The separator used to join all the other items together. Defaults to ', '
+ * @param array $list The list to be joined.
+ * @param string $and The word used to join the last and second last items together with. Defaults to 'and'.
+ * @param string $separator The separator used to join all the other items together. Defaults to ', '.
  * @return string The glued together string.
  * @see String::toList()
  * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/text.html#TextHelper::toList
  */
-	public function toList($list, $and = 'and', $separator = ', ') {
+	public function toList($list, $and = null, $separator = ', ') {
 		return $this->_engine->toList($list, $and, $separator);
 	}
 

+ 2 - 13
src/View/View.php

@@ -927,18 +927,7 @@ class View {
 				return $path . $name . $this->_ext;
 			}
 		}
-		$defaultPath = $paths[0];
-
-		if ($this->plugin) {
-			$pluginPaths = App::objects('Plugin');
-			foreach ($paths as $path) {
-				if (strpos($path, $pluginPaths[0]) === 0) {
-					$defaultPath = $path;
-					break;
-				}
-			}
-		}
-		throw new Error\MissingViewException(array('file' => $defaultPath . $name . $this->_ext));
+		throw new Error\MissingViewException(array('file' => $name . $this->_ext));
 	}
 
 /**
@@ -988,7 +977,7 @@ class View {
 				return $path . $file . $this->_ext;
 			}
 		}
-		throw new Error\MissingLayoutException(array('file' => $paths[0] . $file . $this->_ext));
+		throw new Error\MissingLayoutException(array('file' => $file . $this->_ext));
 	}
 
 /**

+ 14 - 56
src/basics.php

@@ -547,14 +547,8 @@ if (!function_exists('__')) {
 		}
 
 		$translated = I18n::translate($singular);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 1);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 1));
 	}
 
 }
@@ -578,14 +572,8 @@ if (!function_exists('__n')) {
 		}
 
 		$translated = I18n::translate($singular, $plural, null, I18n::LC_MESSAGES, $count);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 3);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 3));
 	}
 
 }
@@ -606,14 +594,8 @@ if (!function_exists('__d')) {
 			return;
 		}
 		$translated = I18n::translate($msg, null, $domain);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 2);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 2));
 	}
 
 }
@@ -638,14 +620,8 @@ if (!function_exists('__dn')) {
 			return;
 		}
 		$translated = I18n::translate($singular, $plural, $domain, I18n::LC_MESSAGES, $count);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 4);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 4));
 	}
 
 }
@@ -681,14 +657,8 @@ if (!function_exists('__dc')) {
 			return;
 		}
 		$translated = I18n::translate($msg, null, $domain, $category);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 3);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 3));
 	}
 
 }
@@ -728,14 +698,8 @@ if (!function_exists('__dcn')) {
 			return;
 		}
 		$translated = I18n::translate($singular, $plural, $domain, $category, $count);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 5);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 5));
 	}
 
 }
@@ -767,14 +731,8 @@ if (!function_exists('__c')) {
 			return;
 		}
 		$translated = I18n::translate($msg, null, null, $category);
-		if ($args === null) {
-			return $translated;
-		} elseif (!is_array($args)) {
-			$args = array_slice(func_get_args(), 2);
-		}
-
-		$translated = preg_replace('/(?<!%)%(?![%\'\-+bcdeEfFgGosuxX\d\.])/', '%%', $translated);
-		return vsprintf($translated, $args);
+		$arguments = func_get_args();
+		return I18n::insertArgs($translated, array_slice($arguments, 2));
 	}
 
 }

+ 9 - 0
tests/TestCase/Utility/HashTest.php

@@ -868,10 +868,19 @@ class HashTest extends TestCase {
 				'active' => false
 			),
 		);
+		$result = Hash::extract($users, '{n}[active=0]');
+		$this->assertCount(1, $result);
+		$this->assertEquals($users[2], $result[0]);
+
 		$result = Hash::extract($users, '{n}[active=false]');
 		$this->assertCount(1, $result);
 		$this->assertEquals($users[2], $result[0]);
 
+		$result = Hash::extract($users, '{n}[active=1]');
+		$this->assertCount(2, $result);
+		$this->assertEquals($users[0], $result[0]);
+		$this->assertEquals($users[1], $result[1]);
+
 		$result = Hash::extract($users, '{n}[active=true]');
 		$this->assertCount(2, $result);
 		$this->assertEquals($users[0], $result[0]);

+ 65 - 37
tests/TestCase/View/Helper/TextHelperTest.php

@@ -371,54 +371,82 @@ class TextHelperTest extends TestCase {
 	}
 
 /**
- * testAutoLinkEmails method
+ * Data provider for autoLinkEmail.
  *
  * @return void
  */
-	public function testAutoLinkEmails() {
-		$text = 'This is a test text';
-		$expected = 'This is a test text';
-		$result = $this->Text->autoLinkUrls($text);
-		$this->assertEquals($expected, $result);
+	public function autoLinkEmailProvider() {
+		return array(
+			array(
+				'This is a test text',
+				'This is a test text',
+			),
 
-		$text = 'email@example.com address';
-		$expected = '<a href="mailto:email@example.com">email@example.com</a> address';
-		$result = $this->Text->autoLinkEmails($text);
-		$this->assertEquals($expected, $result);
+			array(
+				'email@example.com address',
+				'<a href="mailto:email@example.com">email@example.com</a> address',
+			),
 
-		$text = 'email@example.com address';
-		$expected = '<a href="mailto:email@example.com">email@example.com</a> address';
-		$result = $this->Text->autoLinkEmails($text);
-		$this->assertEquals($expected, $result);
+			array(
+				'email@example.com address',
+				'<a href="mailto:email@example.com">email@example.com</a> address',
+			),
 
-		$text = '(email@example.com) address';
-		$expected = '(<a href="mailto:email@example.com">email@example.com</a>) address';
-		$result = $this->Text->autoLinkEmails($text);
-		$this->assertEquals($expected, $result);
+			array(
+				'(email@example.com) address',
+				'(<a href="mailto:email@example.com">email@example.com</a>) address',
+			),
 
-		$text = 'Text with email@example.com address';
-		$expected = 'Text with <a href="mailto:email@example.com">email@example.com</a> address';
-		$result = $this->Text->autoLinkEmails($text);
-		$this->assertEquals($expected, $result);
+			array(
+				'Text with email@example.com address',
+				'Text with <a href="mailto:email@example.com">email@example.com</a> address',
+			),
 
-		$text = "Text with o'hare._-bob@example.com address";
-		$expected = 'Text with <a href="mailto:o&#039;hare._-bob@example.com">o&#039;hare._-bob@example.com</a> address';
-		$result = $this->Text->autoLinkEmails($text);
-		$this->assertEquals($expected, $result);
+			array(
+				"Text with o'hare._-bob@example.com address",
+				'Text with <a href="mailto:o&#039;hare._-bob@example.com">o&#039;hare._-bob@example.com</a> address',
+			),
 
-		$text = 'Text with email@example.com address';
-		$expected = 'Text with <a href="mailto:email@example.com" class="link">email@example.com</a> address';
-		$result = $this->Text->autoLinkEmails($text, array('class' => 'link'));
-		$this->assertEquals($expected, $result);
+			array(
+				'Text with düsentrieb@küchenschöhn-not-working.de address',
+				'Text with <a href="mailto:düsentrieb@küchenschöhn-not-working.de">düsentrieb@küchenschöhn-not-working.de</a> address',
+			),
 
-		$text = 'Text with düsentrieb@küchenschöhn-not-working.de address';
-		$expected = 'Text with <a href="mailto:düsentrieb@küchenschöhn-not-working.de">düsentrieb@küchenschöhn-not-working.de</a> address';
-		$result = $this->Text->autoLinkEmails($text);
-		$this->assertEquals($expected, $result);
+			array(
+				'Text with me@subdomain.küchenschöhn.de address',
+				'Text with <a href="mailto:me@subdomain.küchenschöhn.de">me@subdomain.küchenschöhn.de</a> address',
+			),
+
+			array(
+				'Text with email@example.com address',
+				'Text with <a href="mailto:email@example.com" class="link">email@example.com</a> address',
+				array('class' => 'link'),
+			),
 
-		$text = 'Text with me@subdomain.küchenschöhn.de address';
-		$expected = 'Text with <a href="mailto:me@subdomain.küchenschöhn.de">me@subdomain.küchenschöhn.de</a> address';
-		$result = $this->Text->autoLinkEmails($text);
+			array(
+				'<p>mark@example.com</p>',
+				'<p><a href="mailto:mark@example.com">mark@example.com</a></p>',
+				array('escape' => false)
+			),
+
+			array(
+				'Some&nbsp;mark@example.com&nbsp;Text',
+				'Some&nbsp;<a href="mailto:mark@example.com">mark@example.com</a>&nbsp;Text',
+				array('escape' => false)
+			),
+		);
+	}
+
+/**
+ * testAutoLinkEmails method
+ *
+ * @param string $text The text to link
+ * @param string $expected The expected results.
+ * @dataProvider autoLinkEmailProvider
+ * @return void
+ */
+	public function testAutoLinkEmails($text, $expected, $attrs = array()) {
+		$result = $this->Text->autoLinkEmails($text, $attrs);
 		$this->assertEquals($expected, $result);
 	}