<?php namespace BookStack\Services;
+use BookStack\Exceptions\ImageUploadException;
use BookStack\Image;
+use BookStack\User;
+use Exception;
+use Intervention\Image\Exception\NotSupportedException;
use Intervention\Image\ImageManager;
use Illuminate\Contracts\Filesystem\Factory as FileSystem;
use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance;
$this->cache = $cache;
}
- public function saveNew(Image $image, UploadedFile $uploadedFile, $type)
+ /**
+ * Saves a new image from an upload.
+ * @param UploadedFile $uploadedFile
+ * @param string $type
+ * @return mixed
+ */
+ public function saveNewFromUpload(UploadedFile $uploadedFile, $type)
+ {
+ $imageName = $uploadedFile->getClientOriginalName();
+ $imageData = file_get_contents($uploadedFile->getRealPath());
+ return $this->saveNew($imageName, $imageData, $type);
+ }
+
+
+ /**
+ * Gets an image from url and saves it to the database.
+ * @param $url
+ * @param string $type
+ * @param bool|string $imageName
+ * @return mixed
+ * @throws \Exception
+ */
+ private function saveNewFromUrl($url, $type, $imageName = false)
+ {
+ $imageName = $imageName ? $imageName : basename($url);
+ $imageData = file_get_contents($url);
+ if($imageData === false) throw new \Exception('Cannot get image from ' . $url);
+ return $this->saveNew($imageName, $imageData, $type);
+ }
+
+ /**
+ * Saves a new image
+ * @param string $imageName
+ * @param string $imageData
+ * @param string $type
+ * @return Image
+ * @throws ImageUploadException
+ */
+ private function saveNew($imageName, $imageData, $type)
{
$storage = $this->getStorage();
$secureUploads = Setting::get('app-secure-images');
- $imageName = str_replace(' ', '-', $uploadedFile->getClientOriginalName());
+ $imageName = str_replace(' ', '-', $imageName);
if ($secureUploads) $imageName = str_random(16) . '-' . $imageName;
}
$fullPath = $imagePath . $imageName;
- $storage->put($fullPath, file_get_contents($uploadedFile->getRealPath()));
+ try {
+ $storage->put($fullPath, $imageData);
+ } catch (Exception $e) {
+ throw new ImageUploadException('Image Path ' . $fullPath . ' is not writable by the server.');
+ }
+
+ $imageDetails = [
+ 'name' => $imageName,
+ 'path' => $fullPath,
+ 'url' => $this->getPublicUrl($fullPath),
+ 'type' => $type
+ ];
+
+ if (auth()->user() && auth()->user()->id !== 0) {
+ $userId = auth()->user()->id;
+ $imageDetails['created_by'] = $userId;
+ $imageDetails['updated_by'] = $userId;
+ }
- $userId = auth()->user()->id;
- $image = $image->forceCreate([
- 'name' => $imageName,
- 'path' => $fullPath,
- 'url' => $this->getPublicUrl($fullPath),
- 'type' => $type,
- 'created_by' => $userId,
- 'updated_by' => $userId
- ]);
+ $image = Image::forceCreate($imageDetails);
return $image;
}
* Checks the cache then storage to avoid creating / accessing the filesystem on every check.
*
* @param Image $image
- * @param int $width
- * @param int $height
- * @param bool $keepRatio
+ * @param int $width
+ * @param int $height
+ * @param bool $keepRatio
* @return string
+ * @throws Exception
+ * @throws ImageUploadException
*/
public function getThumbnail(Image $image, $width = 220, $height = 220, $keepRatio = false)
{
return $this->getPublicUrl($thumbFilePath);
}
- // Otherwise create the thumbnail
- $thumb = $this->imageTool->make($storage->get($image->path));
+ try {
+ $thumb = $this->imageTool->make($storage->get($image->path));
+ } catch (Exception $e) {
+ if ($e instanceof \ErrorException || $e instanceof NotSupportedException) {
+ throw new ImageUploadException('The server cannot create thumbnails. Please check you have the GD PHP extension installed.');
+ } else {
+ throw $e;
+ }
+ }
+
if ($keepRatio) {
$thumb->resize($width, null, function ($constraint) {
$constraint->aspectRatio();
return true;
}
+ /**
+ * Save a gravatar image and set a the profile image for a user.
+ * @param User $user
+ * @param int $size
+ * @return mixed
+ */
+ public function saveUserGravatar(User $user, $size = 500)
+ {
+ $emailHash = md5(strtolower(trim($user->email)));
+ $url = 'http://www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon';
+ $imageName = str_replace(' ', '-', $user->name . '-gravatar.png');
+ $image = $this->saveNewFromUrl($url, 'user', $imageName);
+ $image->created_by = $user->id;
+ $image->updated_by = $user->id;
+ $image->save();
+ return $image;
+ }
+
/**
* Get the storage that will be used for storing images.
* @return FileSystemInstance
{
if ($this->storageInstance !== null) return $this->storageInstance;
- $storageType = env('STORAGE_TYPE');
+ $storageType = config('filesystems.default');
$this->storageInstance = $this->fileSystem->disk($storageType);
return $this->storageInstance;
private function getPublicUrl($filePath)
{
if ($this->storageUrl === null) {
- $storageUrl = env('STORAGE_URL');
+ $storageUrl = config('filesystems.url');
// Get the standard public s3 url if s3 is set as storage type
- if ($storageUrl == false && env('STORAGE_TYPE') === 's3') {
+ if ($storageUrl == false && config('filesystems.default') === 's3') {
$storageDetails = config('filesystems.disks.s3');
$storageUrl = 'https://s3-' . $storageDetails['region'] . '.amazonaws.com/' . $storageDetails['bucket'];
}