public function onCreateFileImageThumbnailSource(File $file, &$imgPath, $media = null) { // If we are on a private node, we won't do any remote calls (just as a precaution until // we can configure this from config.php for the private nodes) if (common_config('site', 'private')) { return true; } if ($media !== 'image') { return true; } // If there is a local filename, it is either a local file already or has already been downloaded. if (!empty($file->filename)) { return true; } $this->checkWhitelist($file->getUrl()); // First we download the file to memory and test whether it's actually an image file $imgData = HTTPClient::quickGet($file->getUrl()); common_debug(sprintf('Downloading remote file id==%u with URL: %s', $file->id, $file->getUrl())); $info = @getimagesizefromstring($imgData); if ($info === false) { throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $file->getUrl()); } elseif (!$info[0] || !$info[1]) { throw new UnsupportedMediaException(_('Image file had impossible geometry (0 width or height)')); } $filehash = hash(File::FILEHASH_ALG, $imgData); try { // Exception will be thrown before $file is set to anything, so old $file value will be kept $file = File::getByHash($filehash); //FIXME: Add some code so we don't have to store duplicate File rows for same hash files. } catch (NoResultException $e) { $filename = $filehash . '.' . common_supported_mime_to_ext($info['mime']); $fullpath = File::path($filename); // Write the file to disk if it doesn't exist yet. Throw Exception on failure. if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) { throw new ServerException(_('Could not write downloaded file to disk.')); } // Updated our database for the file record $orig = clone $file; $file->filehash = $filehash; $file->filename = $filename; $file->width = $info[0]; // array indexes documented on php.net: $file->height = $info[1]; // https://php.net/manual/en/function.getimagesize.php // Throws exception on failure. $file->updateWithKeys($orig, 'id'); } // Get rid of the file from memory unset($imgData); $imgPath = $file->getPath(); return false; }
static function fromFilehandle($fh, Profile $scoped) { $stream = stream_get_meta_data($fh); // So far we're only handling filehandles originating from tmpfile(), // so we can always do hash_file on $stream['uri'] as far as I can tell! $filehash = hash_file(File::FILEHASH_ALG, $stream['uri']); try { $file = File::getByHash($filehash); // Already have it, so let's reuse the locally stored File $filename = $file->filename; $mimetype = $file->mimetype; } catch (NoResultException $e) { File::respectsQuota($scoped, filesize($stream['uri'])); $mimetype = self::getUploadedMimeType($stream['uri']); switch (common_config('attachments', 'filename_base')) { case 'upload': $filename = File::filename($scoped, "email", $mimetype); break; case 'hash': default: $filename = strtolower($filehash) . '.' . File::guessMimeExtension($mimetype); } $filepath = File::path($filename); $result = copy($stream['uri'], $filepath) && chmod($filepath, 0664); if (!$result) { // TRANS: Client exception thrown when a file upload operation fails because the file could // TRANS: not be moved from the temporary folder to the permanent file location. throw new ClientException(_('File could not be moved to destination directory.' . $stream['uri'] . ' ' . $filepath)); } } return new MediaFile($scoped, $filename, $mimetype, $filehash); }