]> BookStack Code Mirror - bookstack/blobdiff - app/Services/ImageService.php
Fixed German translations for notifications
[bookstack] / app / Services / ImageService.php
index e83c1860b246f9fcf250e97a6aeed15252a3c32c..73a677ac23ecf144634b3447aff95c83b45c1fd8 100644 (file)
@@ -2,8 +2,8 @@
 
 use BookStack\Exceptions\ImageUploadException;
 use BookStack\Image;
-use BookStack\ImageRevision;
 use BookStack\User;
+use DB;
 use Exception;
 use Intervention\Image\Exception\NotSupportedException;
 use Intervention\Image\ImageManager;
@@ -17,15 +17,18 @@ class ImageService extends UploadService
     protected $imageTool;
     protected $cache;
     protected $storageUrl;
+    protected $image;
 
     /**
      * ImageService constructor.
-     * @param $imageTool
-     * @param $fileSystem
-     * @param $cache
+     * @param Image $image
+     * @param ImageManager $imageTool
+     * @param FileSystem $fileSystem
+     * @param Cache $cache
      */
-    public function __construct(ImageManager $imageTool, FileSystem $fileSystem, Cache $cache)
+    public function __construct(Image $image, ImageManager $imageTool, FileSystem $fileSystem, Cache $cache)
     {
+        $this->image = $image;
         $this->imageTool = $imageTool;
         $this->cache = $cache;
         parent::__construct($fileSystem);
@@ -82,22 +85,6 @@ class ImageService extends UploadService
         return $this->saveNew($name, $data, $type, $uploadedTo);
     }
 
-    /**
-     * @param Image $image
-     * @param string $base64Uri
-     * @return Image
-     * @throws ImageUploadException
-     */
-    public function updateImageFromBase64Uri(Image $image, string $base64Uri)
-    {
-        $splitData = explode(';base64,', $base64Uri);
-        if (count($splitData) < 2) {
-            throw new ImageUploadException("Invalid base64 image data provided");
-        }
-        $data = base64_decode($splitData[1]);
-        return $this->update($image, $data);
-    }
-
     /**
      * Gets an image from url and saves it to the database.
      * @param             $url
@@ -131,16 +118,16 @@ class ImageService extends UploadService
         $secureUploads = setting('app-secure-images');
         $imageName = str_replace(' ', '-', $imageName);
 
-        if ($secureUploads) {
-            $imageName = str_random(16) . '-' . $imageName;
-        }
-
         $imagePath = '/uploads/images/' . $type . '/' . Date('Y-m-M') . '/';
 
         while ($storage->exists($imagePath . $imageName)) {
             $imageName = str_random(3) . $imageName;
         }
+
         $fullPath = $imagePath . $imageName;
+        if ($secureUploads) {
+            $fullPath = $imagePath . str_random(16) . '-' . $imageName;
+        }
 
         try {
             $storage->put($fullPath, $imageData);
@@ -163,64 +150,11 @@ class ImageService extends UploadService
             $imageDetails['updated_by'] = $userId;
         }
 
-        $image = (new Image());
+        $image = $this->image->newInstance();
         $image->forceFill($imageDetails)->save();
         return $image;
     }
 
-    /**
-     * Update the content of an existing image.
-     * Uploaded the new image content and creates a revision for the old image content.
-     * @param Image $image
-     * @param $imageData
-     * @return Image
-     * @throws ImageUploadException
-     */
-    private function update(Image $image, $imageData)
-    {
-        // Save image revision if not previously exists to ensure we always have
-        // a reference to the image files being uploaded.
-        if ($image->revisions()->count() === 0) {
-            $this->saveImageRevision($image);
-        }
-
-        $pathInfo = pathinfo($image->path);
-        $revisionCount = $image->revisionCount() + 1;
-        $newFileName = preg_replace('/^(.+?)(-v\d+)?$/', '$1-v' . $revisionCount, $pathInfo['filename']);
-
-        $image->path = str_replace_last($pathInfo['filename'], $newFileName, $image->path);
-        $image->url = $this->getPublicUrl($image->path);
-        $image->updated_by = user()->id;
-
-        $storage = $this->getStorage();
-
-        try {
-            $storage->put($image->path, $imageData);
-            $storage->setVisibility($image->path, 'public');
-            $image->save();
-            $this->saveImageRevision($image);
-        } catch (Exception $e) {
-            throw new ImageUploadException(trans('errors.path_not_writable', ['filePath' => $image->path]));
-        }
-        return $image;
-    }
-
-    /**
-     * Save a new revision for an image.
-     * @param Image $image
-     * @return ImageRevision
-     */
-    protected function saveImageRevision(Image $image)
-    {
-        $revision = new ImageRevision();
-        $revision->image_id = $image->id;
-        $revision->path = $image->path;
-        $revision->url = $image->url;
-        $revision->created_by = user()->id;
-        $revision->revision = $image->revisionCount() + 1;
-        $revision->save();
-        return $revision;
-    }
 
     /**
      * Checks if the image is a gif. Returns true if it is, else false.
@@ -309,13 +243,6 @@ class ImageService extends UploadService
      */
     public function destroy(Image $image)
     {
-        // Destroy image revisions
-        foreach ($image->revisions as $revision) {
-            $this->destroyImagesFromPath($revision->path);
-            $revision->delete();
-        }
-
-        // Destroy main image
         $this->destroyImagesFromPath($image->path);
         $image->delete();
     }
@@ -371,6 +298,46 @@ class ImageService extends UploadService
         return $image;
     }
 
+
+    /**
+     * Delete gallery and drawings that are not within HTML content of pages or page revisions.
+     * Checks based off of only the image name.
+     * Could be much improved to be more specific but kept it generic for now to be safe.
+     *
+     * Returns the path of the images that would be/have been deleted.
+     * @param bool $checkRevisions
+     * @param bool $dryRun
+     * @param array $types
+     * @return array
+     */
+    public function deleteUnusedImages($checkRevisions = true, $dryRun = true, $types = ['gallery', 'drawio'])
+    {
+        $types = array_intersect($types, ['gallery', 'drawio']);
+        $deletedPaths = [];
+
+        $this->image->newQuery()->whereIn('type', $types)
+            ->chunk(1000, function($images) use ($types, $checkRevisions, &$deletedPaths, $dryRun) {
+             foreach ($images as $image) {
+                 $searchQuery = '%' . basename($image->path) . '%';
+                 $inPage = DB::table('pages')
+                         ->where('html', 'like', $searchQuery)->count() > 0;
+                 $inRevision = false;
+                 if ($checkRevisions) {
+                     $inRevision =  DB::table('page_revisions')
+                             ->where('html', 'like', $searchQuery)->count() > 0;
+                 }
+
+                 if (!$inPage && !$inRevision) {
+                     $deletedPaths[] = $image->path;
+                     if (!$dryRun) {
+                         $this->destroy($image);
+                     }
+                 }
+             }
+        });
+        return $deletedPaths;
+    }
+
     /**
      * Convert a image URI to a Base64 encoded string.
      * Attempts to find locally via set storage method first.