Browse Source

Made specifying 'extension' optional. Fixed bug where downloaded file did not have extension when 'name' was specified. Fixes #2554

ADmad 14 years ago
parent
commit
bf700c826a
2 changed files with 37 additions and 5 deletions
  1. 26 2
      lib/Cake/Test/Case/View/MediaViewTest.php
  2. 11 3
      lib/Cake/View/MediaView.php

+ 26 - 2
lib/Cake/Test/Case/View/MediaViewTest.php

@@ -244,6 +244,7 @@ class MediaViewTest extends CakeTestCase {
 			'path' =>  CAKE . 'Test' . DS . 'test_app' . DS . 'Config' . DS,
 			'id' => 'no_section.ini',
 			'extension' => 'ini',
+			'name' => 'config'
 		);
 		$this->MediaView->expects($this->exactly(2))
 			->method('_isActive')
@@ -270,7 +271,7 @@ class MediaViewTest extends CakeTestCase {
 
 		$this->MediaView->response->expects($this->once())
 			->method('download')
-			->with('no_section.ini');
+			->with('config.ini');
 
 		$this->MediaView->response->expects($this->at(4))
 			->method('header')
@@ -357,7 +358,7 @@ class MediaViewTest extends CakeTestCase {
  *
  * @return void
  */
-	function testRenderUpperExtesnion() {
+	public function testRenderUpperExtension() {
 		$this->MediaView->viewVars = array(
 			'path' =>  CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS .'img' . DS,
 			'id' => 'test_2.JPG',
@@ -376,4 +377,27 @@ class MediaViewTest extends CakeTestCase {
 		$this->MediaView->render();
 	}
 
+/**
+ * Test downloading files with extension not explicitly set.
+ *
+ * @return void
+ */
+	public function testRenderExtensionNotSet() {
+		$this->MediaView->viewVars = array(
+			'path' =>  CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS .'img' . DS,
+			'id' => 'test_2.JPG',
+		);
+
+		$this->MediaView->response->expects($this->any())
+			->method('type')
+			->with('jpg')
+			->will($this->returnArgument(0));
+
+		$this->MediaView->expects($this->at(0))
+			->method('_isActive')
+			->will($this->returnValue(true));
+
+		$this->MediaView->render();
+	}
+
 }

+ 11 - 3
lib/Cake/View/MediaView.php

@@ -31,9 +31,11 @@ App::uses('CakeRequest', 'Network');
  * - `id` The filename on the server's filesystem, including extension.
  * - `name` The filename that will be sent to the user, specified without the extension.
  * - `download` Set to true to set a `Content-Disposition` header.  This is ideal for file downloads.
- * - `extension` The extension of the file being served.  This is used to set the mimetype
+ * - `extension` The extension of the file being served. This is used to set the mimetype.
+ * 	If not provided its extracted from filename provided as `id`.
  * - `path` The absolute path, including the trailing / on the server's filesystem to `id`.
  * - `mimeType` The mime type of the file if CakeResponse doesn't know about it.
+ * 	Must be an associative array with extension as key and mime type as value eg. array('ini' => 'text/plain')
  *
  * ### Usage
  *
@@ -113,7 +115,11 @@ class MediaView extends View {
 			$this->response->type($mimeType);
 		}
 
-		if (isset($extension) && $this->_isActive()) {
+		if (!isset($extension)) {
+			$extension = pathinfo($id, PATHINFO_EXTENSION);
+		}
+
+		if ($this->_isActive()) {
 			$extension = strtolower($extension);
 			$chunkSize = 8192;
 			$buffer = '';
@@ -128,7 +134,7 @@ class MediaView extends View {
 			} else {
 				$modified = time();
 			}
-			if ($this->response->type($extension) === false) {
+			if (!$extension || $this->response->type($extension) === false) {
 				$download = true;
 			}
 
@@ -157,6 +163,8 @@ class MediaView extends View {
 				}
 				if (is_null($name)) {
 					$name = $id;
+				} elseif ($extension) {
+					$name .= '.' . $extension;
 				}
 				$this->response->download($name);
 				$this->response->header(array('Accept-Ranges' => 'bytes'));