Permalink
Browse files

fix(files): files with custom filestore can now be served via file se…

…rvice

Adds the logic to serve files by their GUID with full application boot, if they have
a custom filestore
  • Loading branch information...
hypeJunction authored and mrclay committed Dec 26, 2015
1 parent 27a90a4 commit 1a2b0ca7170e7bbe949208de8d8321278cb4843d
@@ -396,6 +396,11 @@ public function run() {
return true;
}
+ if (0 === strpos($path, '/download-file/')) {
+ (new Application\DownloadFileHandler($this))->getResponse($this->services->request)->send();
+ return true;
+ }
+
if ($path === '/rewrite.php') {
require Directory\Local::root()->getPath("install.php");
return true;
@@ -0,0 +1,82 @@
+<?php
+
+namespace Elgg\Application;
+
+use DateTime;
+use Elgg\Application;
+use Elgg\Http\Request;
+use ElggFile;
+use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * File download handler for files with custom filestore
+ *
+ * @access private
+ *
+ * @package Elgg.Core
+ */
+class DownloadFileHandler {
+
+ /** @var Application */
+ private $application;
+
+ /**
+ * Constructor
+ *
+ * @param Application $app Elgg Application
+ */
+ public function __construct(Application $app) {
+ $this->application = $app;
+ }
+
+ /**
+ * Handle a request for a file
+ *
+ * @param Request $request HTTP request
+ * @return Response
+ */
+ public function getResponse($request) {
+
+ $response = new Response();
+ $response->prepare($request);
+
+ $path = implode('/', $request->getUrlSegments());
+ if (!preg_match('~download-file/g(\d+)$~', $path, $m)) {
+ return $response->setStatusCode(400)->setContent('Malformatted request URL');
+ }
+
+ $this->application->start();
+
+ $guid = (int) $m[1];
+ $file = get_entity($guid);
+
+ if (!$file instanceof ElggFile) {
+ return $response->setStatusCode(404)->setContent("File with guid $guid does not exist");
+ }
+
+ $filenameonfilestore = $file->getFilenameOnFilestore();
+
+ if (!is_readable($filenameonfilestore)) {
+ return $response->setStatusCode(404)->setContent('File not found');
+ }
+
+ $last_updated = filemtime($filenameonfilestore);
+ $etag = '"' . $last_updated . '"';
+ $response->setPublic()->setEtag($etag);
+ if ($response->isNotModified($request)) {
+ return $response;
+ }
+
+ $response = new BinaryFileResponse($filenameonfilestore, 200, array(), false, 'attachment');
+ $response->prepare($request);
+
+ $expires = strtotime('+1 year');
+ $expires_dt = (new DateTime())->setTimestamp($expires);
+ $response->setExpires($expires_dt);
+
+ $response->setEtag($etag);
+ return $response;
+ }
+
+}
@@ -94,6 +94,14 @@ public function getURL() {
}
if (!$relative_path) {
+ // File object has a custom filestore
+ if ($this->file->guid) {
+ $url_segments = array(
+ 'download-file',
+ "g{$this->file->guid}"
+ );
+ return elgg_normalize_url(implode('/', $url_segments));
+ }
elgg_log("Unable to resolve relative path of the file on the filestore");
return false;
}

0 comments on commit 1a2b0ca

Please sign in to comment.