Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Template Questions /

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba

how to download pdf file ?


Go to End
Reply


10 Posts   7029 Views

Avatar
inCharge

Community Member, 102 Posts

19 July 2011 at 5:54am

Edited: 19/07/2011 7:13am


> I really don't thinkit's necessary to start throwing HTTP headers for a PDF download

The problem is if the PDF files are big and/or the server is slow, the browser gives no progress indication, so after 5 seconds, people give up and click Back. If it's a download, then they get a pop-up as soon as they click, then they get progress indication. Far more users see the download through to completion.


> send_file() is a function on HTTPRequest not HTTPResponse.

True, SS_HTTPRequest::send_file works for me.

OK, here's a working example, using SilverStripe 2.4.5

I have multiple DataObject classes that have a file field called Document (among other fields of course)...

class NewsObject extends DataObject {

	public static $has_one = array(
		 'Document' => 'File'
	);

	public function getCMSFields_forPopup() {
			new FileIFrameField('Document', 'File', null, null, null, self::$defaultFileFolder)
		);
	}

In the Page_Controller, I add a download action for each of the DataObject classes...

class Page_Controller extends ContentController {

	public static $allowed_actions = array (
		'downloadevent', 'downloadnews'
	);

	.
	.
	.

	private function download($classname) {

		$id = intval( Director::URLParam('ID') );
		$object = $id ? DataObject::get_one($classname, 'ID=' . $id ) : null;
		$document = $object ? $object->Document() : null;

		if ( $document )
			return SS_HTTPRequest::send_file(file_get_contents($document->getFullPath()), $document->getFilename() );
		else
			return $this->httpError(404);
	}
	public function downloadevent() {
		return $this->download('EventObject');
	}
	public function downloadnews() {
		return $this->download('NewsObject');
	}
	function BaseUrl() {
		return Director::baseURL() . $this->URLSegment;
	}
}

...so all page types inherit the download functionality, and the download actions can be used in any .ss file...

	<% control NewsObjects %>
		<a href="$Top.BaseUrl/downloadnews/$ID">
	<% end_control %>

	<% control EventObjects %>
		<a href="$Top.BaseUrl/downloadevent/$ID">
	<% end_control %>

Avatar
zenmonkey

Community Member, 541 Posts

23 July 2011 at 8:02am

FYI soon this will all become redundant. A download property is being added the a element in html5

http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#attr-hyperlink-download

Yay!

Go to Top