Browse Source

Merge branch 'master' into 2.3

mark_story 13 years ago
parent
commit
9a66768aa4

+ 0 - 1
lib/Cake/Error/ErrorHandler.php

@@ -22,7 +22,6 @@
 App::uses('Debugger', 'Utility');
 App::uses('CakeLog', 'Log');
 App::uses('ExceptionRenderer', 'Error');
-App::uses('AppController', 'Controller');
 
 /**
  *

+ 24 - 15
lib/Cake/Log/CakeLog.php

@@ -67,6 +67,7 @@ App::uses('LogEngineCollection', 'Log');
  * application.  By using scopes you can control logging for each part
  * of your application and still keep standard log levels.
  *
+ *
  * See CakeLog::config() and CakeLog::write() for more information
  * on scopes
  *
@@ -173,7 +174,10 @@ class CakeLog {
  *
  * The above logger will only capture log entries made in the
  * `payment` and `order` scopes. All other scopes including the
- * undefined scope will be ignored.
+ * undefined scope will be ignored. Its important to remember that
+ * when using scopes you must also define the `types` of log messages
+ * that a logger will handle. Failing to do so will result in the logger
+ * catching all log messages even if the scope is incorrect.
  *
  * @param string $key The keyname for this logger, used to remove the
  *    logger later.
@@ -422,24 +426,29 @@ class CakeLog {
 		$logged = false;
 		foreach (self::$_Collection->enabled() as $streamName) {
 			$logger = self::$_Collection->{$streamName};
-			$types = null;
-			$scopes = array();
+			$types = $scopes = $config = array();
 			if ($logger instanceof BaseLog) {
 				$config = $logger->config();
-				if (isset($config['types'])) {
-					$types = $config['types'];
-				}
-				if (isset($config['scopes'])) {
-					$scopes = $config['scopes'];
-				}
 			}
-			if (is_string($scope)) {
-				$inScope = in_array($scope, $scopes);
-			} else {
-				$intersect = array_intersect($scope, $scopes);
-				$inScope = !empty($intersect);
+			if (isset($config['types'])) {
+				$types = $config['types'];
+			}
+			if (isset($config['scopes'])) {
+				$scopes = $config['scopes'];
 			}
-			if (empty($types) || in_array($type, $types) || in_array($type, $scopes) && $inScope) {
+			$inScope = (count(array_intersect((array)$scope, $scopes)) > 0);
+			$correctLevel = in_array($type, $types);
+
+			if (
+				// No config is a catch all (bc mode)
+				(empty($types) && empty($scopes)) ||
+				// BC layer for mixing scope & level
+				(in_array($type, $scopes)) ||
+				// no scopes, but has level
+				(empty($scopes) && $correctLevel) ||
+				// exact scope + level
+				($correctLevel && $inScope)
+			) {
 				$logger->write($type, $message);
 				$logged = true;
 			}

+ 36 - 17
lib/Cake/Test/Case/Log/CakeLogTest.php

@@ -331,21 +331,22 @@ class CakeLogTest extends CakeTestCase {
 
 /**
  * test backward compatible scoped logging
+ *
+ * @return void
  */
 	public function testScopedLoggingBC() {
-		$this->_deleteLogs();
-
 		$this->_resetLogConfig();
+
 		CakeLog::config('shops', array(
 			'engine' => 'FileLog',
 			'types' => array('info', 'notice', 'warning'),
 			'scopes' => array('transactions', 'orders'),
 			'file' => 'shops',
-			));
+		));
+		$this->_deleteLogs();
 
 		CakeLog::write('info', 'info message');
 		$this->assertFalse(file_exists(LOGS . 'error.log'));
-		$this->assertTrue(file_exists(LOGS . 'shops.log'));
 		$this->assertTrue(file_exists(LOGS . 'debug.log'));
 
 		$this->_deleteLogs();
@@ -375,7 +376,6 @@ class CakeLogTest extends CakeTestCase {
 
 		CakeLog::write('warning', 'warning message');
 		$this->assertTrue(file_exists(LOGS . 'error.log'));
-		$this->assertTrue(file_exists(LOGS . 'shops.log'));
 		$this->assertFalse(file_exists(LOGS . 'debug.log'));
 
 		$this->_deleteLogs();
@@ -383,29 +383,48 @@ class CakeLogTest extends CakeTestCase {
 		CakeLog::drop('shops');
 	}
 
+
+	public function testScopedLoggingExclusive() {
+		$this->_deleteLogs();
+
+		CakeLog::config('shops', array(
+			'engine' => 'FileLog',
+			'types' => array('info', 'notice', 'warning'),
+			'scopes' => array('transactions', 'orders'),
+			'file' => 'shops.log',
+		));
+		CakeLog::config('eggs', array(
+			'engine' => 'FileLog',
+			'types' => array('info', 'notice', 'warning'),
+			'scopes' => array('eggs'),
+			'file' => 'eggs.log',
+		));
+
+		CakeLog::write('info', 'transactions message', 'transactions');
+		$this->assertFalse(file_exists(LOGS . 'eggs.log'));
+		$this->assertTrue(file_exists(LOGS . 'shops.log'));
+
+		$this->_deleteLogs();
+
+		CakeLog::write('info', 'eggs message', 'eggs');
+		$this->assertTrue(file_exists(LOGS . 'eggs.log'));
+		$this->assertFalse(file_exists(LOGS . 'shops.log'));
+	}
+
 /**
  * test scoped logging
  *
  * @return void
  */
 	public function testScopedLogging() {
-		if (file_exists(LOGS . 'shops.log')) {
-			unlink(LOGS . 'shops.log');
-		}
-		if (file_exists(LOGS . 'error.log')) {
-			unlink(LOGS . 'error.log');
-		}
-		if (file_exists(LOGS . 'debug.log')) {
-			unlink(LOGS . 'debug.log');
-		}
-
 		$this->_resetLogConfig();
+		$this->_deleteLogs();
 		CakeLog::config('shops', array(
 			'engine' => 'FileLog',
 			'types' => array('info', 'notice', 'warning'),
 			'scopes' => array('transactions', 'orders'),
-			'file' => 'shops',
-			));
+			'file' => 'shops.log',
+		));
 
 		CakeLog::write('info', 'info message', 'transactions');
 		$this->assertFalse(file_exists(LOGS . 'error.log'));

+ 7 - 1
lib/Cake/TestSuite/Fixture/CakeTestFixture.php

@@ -97,7 +97,13 @@ class CakeTestFixture {
 		if (!empty($this->useDbConfig)) {
 			$connection = $this->useDbConfig;
 			if (strpos($connection, 'test') !== 0) {
-				throw new CakeException(__d('cake_dev', 'Invalid datasource %s for object %s', $connection, $this->name));
+				$message = __d(
+					'cake_dev',
+					'Invalid datasource name "%s" for "%s" fixture. Fixture datasource names must begin with "test".',
+					$connection,
+					$this->name
+				);
+				throw new CakeException($message);
 			}
 		}
 		$this->Schema = new CakeSchema(array('name' => 'TestSuite', 'connection' => $connection));

+ 1 - 1
lib/Cake/Utility/Set.php

@@ -533,7 +533,7 @@ class Set {
  *
  * @param array $data Array from where to extract
  * @param string|array $path As an array, or as a dot-separated string.
- * @return array Extracted data
+ * @return array|null Extracted data or null when $data or $path are empty.
  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::classicExtract
  */
 	public static function classicExtract($data, $path = null) {