diff --git a/lib/Cake/Console/ConsoleOutput.php b/lib/Cake/Console/ConsoleOutput.php index fa021b565..5e1ce9bec 100644 --- a/lib/Cake/Console/ConsoleOutput.php +++ b/lib/Cake/Console/ConsoleOutput.php @@ -295,7 +295,9 @@ class ConsoleOutput { * Clean up and close handles */ public function __destruct() { - fclose($this->_output); + if (is_resource($this->_output)) { + fclose($this->_output); + } } } diff --git a/lib/Cake/Console/Templates/default/classes/controller.ctp b/lib/Cake/Console/Templates/default/classes/controller.ctp index e290a8675..3e5a3004e 100644 --- a/lib/Cake/Console/Templates/default/classes/controller.ctp +++ b/lib/Cake/Console/Templates/default/classes/controller.ctp @@ -74,7 +74,9 @@ class Controller extends App echo ");\n\n"; endif; - echo trim($actions); + if (!empty($actions)) { + echo trim($actions) . "\n"; + } endif; ?> } diff --git a/lib/Cake/Controller/Component/Acl/IniAcl.php b/lib/Cake/Controller/Component/Acl/IniAcl.php index f212938c4..0fa9fd334 100644 --- a/lib/Cake/Controller/Component/Acl/IniAcl.php +++ b/lib/Cake/Controller/Component/Acl/IniAcl.php @@ -43,7 +43,7 @@ class IniAcl extends Object implements AclInterface { /** * Initialize method * - * @param AclBase $component + * @param Component $component * @return void */ public function initialize(Component $component) { diff --git a/lib/Cake/Controller/Component/AclComponent.php b/lib/Cake/Controller/Component/AclComponent.php index 6d0f3b8b4..fc87b3c6e 100644 --- a/lib/Cake/Controller/Component/AclComponent.php +++ b/lib/Cake/Controller/Component/AclComponent.php @@ -21,8 +21,8 @@ App::uses('AclInterface', 'Controller/Component/Acl'); * Access Control List factory class. * * Uses a strategy pattern to allow custom ACL implementations to be used with the same component interface. - * You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. Concrete ACL - * implementations should extend `AclBase` and implement the methods it defines. + * You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. The adapter + * you specify must implement `AclInterface` * * @package Cake.Controller.Component * @link http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html diff --git a/lib/Cake/Model/Datasource/Database/Sqlserver.php b/lib/Cake/Model/Datasource/Database/Sqlserver.php index e7c202c4c..95a4801fd 100644 --- a/lib/Cake/Model/Datasource/Database/Sqlserver.php +++ b/lib/Cake/Model/Datasource/Database/Sqlserver.php @@ -767,6 +767,7 @@ class Sqlserver extends DboSource { */ protected function _execute($sql, $params = array(), $prepareOptions = array()) { $this->_lastAffected = false; + $sql = trim($sql); if (strncasecmp($sql, 'SELECT', 6) === 0 || preg_match('/^EXEC(?:UTE)?\s/mi', $sql) > 0) { $prepareOptions += array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL); return parent::_execute($sql, $params, $prepareOptions); diff --git a/lib/Cake/Routing/Filter/AssetDispatcher.php b/lib/Cake/Routing/Filter/AssetDispatcher.php index 0c91c3cd7..5e545146e 100644 --- a/lib/Cake/Routing/Filter/AssetDispatcher.php +++ b/lib/Cake/Routing/Filter/AssetDispatcher.php @@ -51,19 +51,12 @@ class AssetDispatcher extends DispatcherFilter { } $assetFile = $this->_getAssetFile($url); - if ($assetFile === null) { + if ($assetFile === null || !file_exists($assetFile)) { return null; } - $response = $event->data['response']; $event->stopPropagation(); - if (!file_exists($assetFile)) { - $response->statusCode(404); - $response->send(); - return $response; - } - $response->modified(filemtime($assetFile)); if ($response->checkNotModified($event->data['request'])) { return $response; @@ -71,6 +64,7 @@ class AssetDispatcher extends DispatcherFilter { $pathSegments = explode('.', $url); $ext = array_pop($pathSegments); + $this->_deliverAsset($response, $assetFile, $ext); return $response; } diff --git a/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php b/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php index 375d03067..66d991c4b 100644 --- a/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php +++ b/lib/Cake/Test/Case/Controller/Component/AclComponentTest.php @@ -78,7 +78,7 @@ class AclComponentTest extends CakeTestCase { } /** - * test that adapter() whines when the class is not an AclBase + * test that adapter() whines when the class does not implement AclInterface * * @expectedException CakeException * @return void diff --git a/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php b/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php index 35c261cd8..dc43fda46 100644 --- a/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php +++ b/lib/Cake/Test/Case/Routing/Filter/AssetDispatcherTest.php @@ -83,6 +83,33 @@ class AssetDispatcherTest extends CakeTestCase { $this->assertFalse($event->isStopped()); } +/** + * AssetDispatcher should not 404 extensions that could be handled + * by Routing. + * + * @return void + */ + public function testNoHandleRoutedExtension() { + $filter = new AssetDispatcher(); + $response = $this->getMock('CakeResponse', array('_sendHeader')); + Configure::write('Asset.filter', array( + 'js' => '', + 'css' => '' + )); + App::build(array( + 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS), + 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS) + ), App::RESET); + Router::parseExtensions('json'); + Router::connect('/test_plugin/api/v1/:action', array('controller' => 'api')); + CakePlugin::load('TestPlugin'); + + $request = new CakeRequest('test_plugin/api/v1/forwarding.json'); + $event = new CakeEvent('DispatcherTest', $this, compact('request', 'response')); + $this->assertNull($filter->beforeDispatch($event)); + $this->assertFalse($event->isStopped(), 'Events for routed extensions should not be stopped'); + } + /** * Tests that $response->checkNotModified() is called and bypasses * file dispatching @@ -129,23 +156,6 @@ class AssetDispatcherTest extends CakeTestCase { $this->assertEquals($time->format('D, j M Y H:i:s') . ' GMT', $response->modified()); } -/** - * Test 404 status code is set on missing asset. - * - * @return void - */ - public function test404OnMissingFile() { - $filter = new AssetDispatcher(); - - $response = $this->getMock('CakeResponse', array('_sendHeader')); - $request = new CakeRequest('/theme/test_theme/img/nope.gif'); - $event = new CakeEvent('Dispatcher.beforeRequest', $this, compact('request', 'response')); - - $response = $filter->beforeDispatch($event); - $this->assertTrue($event->isStopped()); - $this->assertEquals(404, $response->statusCode()); - } - /** * Test that no exceptions are thrown for //index.php type URLs. * diff --git a/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php b/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php index 73da81ca4..407045739 100644 --- a/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php +++ b/lib/Cake/TestSuite/Reporter/CakeHtmlReporter.php @@ -264,7 +264,7 @@ class CakeHtmlReporter extends CakeBaseReporter { echo "
" . $this->_htmlEntities($message->toString()); if ((is_string($actualMsg) && is_string($expectedMsg)) || (is_array($actualMsg) && is_array($expectedMsg))) { - echo "
" . PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg); + echo "
" . $this->_htmlEntities(PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg)); } echo "