diff --git a/src/aphront/response/AphrontResponse.php b/src/aphront/response/AphrontResponse.php --- a/src/aphront/response/AphrontResponse.php +++ b/src/aphront/response/AphrontResponse.php @@ -192,19 +192,21 @@ public function getCacheHeaders() { $headers = array(); if ($this->cacheable) { + $cache_control = array(); + $cache_control[] = sprintf('max-age=%d', $this->cacheable); + if ($this->canCDN) { - $headers[] = array( - 'Cache-Control', - 'public', - ); + $cache_control[] = 'public'; } else { - $headers[] = array( - 'Cache-Control', - 'private', - ); + $cache_control[] = 'private'; } $headers[] = array( + 'Cache-Control', + implode(', ', $cache_control), + ); + + $headers[] = array( 'Expires', $this->formatEpochTimestampForHTTPHeader(time() + $this->cacheable), ); diff --git a/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php b/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php --- a/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php +++ b/src/applications/files/markup/PhabricatorEmbedFileRemarkupRule.php @@ -16,6 +16,10 @@ $objects = id(new PhabricatorFileQuery()) ->setViewer($viewer) ->withIDs($ids) + ->needTransforms( + array( + PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW, + )) ->execute(); $phids_key = self::KEY_EMBED_FILE_PHIDS; @@ -109,7 +113,15 @@ default: $preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW; $xform = PhabricatorFileTransform::getTransformByKey($preview_key); - $attrs['src'] = $file->getURIForTransform($xform); + + $existing_xform = $file->getTransform($preview_key); + if ($existing_xform) { + $xform_uri = $existing_xform->getCDNURI(); + } else { + $xform_uri = $file->getURIForTransform($xform); + } + + $attrs['src'] = $xform_uri; $dimensions = $xform->getTransformedDimensions($file); if ($dimensions) { diff --git a/src/applications/files/query/PhabricatorFileQuery.php b/src/applications/files/query/PhabricatorFileQuery.php --- a/src/applications/files/query/PhabricatorFileQuery.php +++ b/src/applications/files/query/PhabricatorFileQuery.php @@ -15,6 +15,7 @@ private $maxLength; private $names; private $isPartial; + private $needTransforms; public function withIDs(array $ids) { $this->ids = $ids; @@ -117,6 +118,11 @@ return $this; } + public function needTransforms(array $transforms) { + $this->needTransforms = $transforms; + return $this; + } + public function newResultObject() { return new PhabricatorFile(); } @@ -218,6 +224,44 @@ return $files; } + protected function didFilterPage(array $files) { + $xform_keys = $this->needTransforms; + if ($xform_keys !== null) { + $xforms = id(new PhabricatorTransformedFile())->loadAllWhere( + 'originalPHID IN (%Ls) AND transform IN (%Ls)', + mpull($files, 'getPHID'), + $xform_keys); + + if ($xforms) { + $xfiles = id(new PhabricatorFile())->loadAllWhere( + 'phid IN (%Ls)', + mpull($xforms, 'getTransformedPHID')); + $xfiles = mpull($xfiles, null, 'getPHID'); + } + + $xform_map = array(); + foreach ($xforms as $xform) { + $xfile = idx($xfiles, $xform->getTransformedPHID()); + if (!$xfile) { + continue; + } + $original_phid = $xform->getOriginalPHID(); + $xform_key = $xform->getTransform(); + $xform_map[$original_phid][$xform_key] = $xfile; + } + + $default_xforms = array_fill_keys($xform_keys, null); + + foreach ($files as $file) { + $file_xforms = idx($xform_map, $file->getPHID(), array()); + $file_xforms += $default_xforms; + $file->attachTransforms($file_xforms); + } + } + + return $files; + } + protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { $joins = parent::buildJoinClauseParts($conn); diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php --- a/src/applications/files/storage/PhabricatorFile.php +++ b/src/applications/files/storage/PhabricatorFile.php @@ -56,6 +56,7 @@ private $objects = self::ATTACHABLE; private $objectPHIDs = self::ATTACHABLE; private $originalFile = self::ATTACHABLE; + private $transforms = self::ATTACHABLE; public static function initializeNewFile() { $app = id(new PhabricatorApplicationQuery()) @@ -1208,6 +1209,15 @@ ->setURI($uri); } + public function attachTransforms(array $map) { + $this->transforms = $map; + return $this; + } + + public function getTransform($key) { + return $this->assertAttachedKey($this->transforms, $key); + } + /* -( PhabricatorApplicationTransactionInterface )------------------------- */