protected function storeRemoteFileThumbnail(File_thumbnail $thumbnail) { if (!empty($thumbnail->filename) && file_exists($thumbnail->getPath())) { throw new AlreadyFulfilledException(sprintf('A thumbnail seems to already exist for remote file with id==%u', $thumbnail->file_id)); } $url = $thumbnail->getUrl(); $this->checkWhitelist($url); // First we download the file to memory and test whether it's actually an image file // FIXME: To support remote video/whatever files, this needs reworking. common_debug(sprintf('Downloading remote thumbnail for file id==%u with thumbnail URL: %s', $thumbnail->file_id, $url)); $imgData = HTTPClient::quickGet($url); $info = @getimagesizefromstring($imgData); if ($info === false) { throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $url); } elseif (!$info[0] || !$info[1]) { throw new UnsupportedMediaException(_('Image file had impossible geometry (0 width or height)')); } // We'll trust sha256 not to have collision issues any time soon :) $filename = hash('sha256', $imgData) . '.' . common_supported_mime_to_ext($info['mime']); $fullpath = File_thumbnail::path($filename); // Write the file to disk. Throw Exception on failure if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) { throw new ServerException(_('Could not write downloaded file to disk.')); } // Get rid of the file from memory unset($imgData); // Updated our database for the file record $orig = clone $thumbnail; $thumbnail->filename = $filename; $thumbnail->width = $info[0]; // array indexes documented on php.net: $thumbnail->height = $info[1]; // https://php.net/manual/en/function.getimagesize.php // Throws exception on failure. $thumbnail->updateWithKeys($orig, 'file_id'); }