namespace BookStack\Entities\Models;
use BookStack\Uploads\Image;
+use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
}
/**
- * Returns BookShelf cover image, if cover does not exists return default cover image.
- *
- * @param int $width - Width of the image
- * @param int $height - Height of the image
- *
- * @return string
+ * Returns shelf cover image, if cover not exists return default cover image.
*/
- public function getBookCover($width = 440, $height = 250)
+ public function getBookCover(int $width = 440, int $height = 250): string
{
// TODO - Make generic, focused on books right now, Perhaps set-up a better image
$default = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
- if (!$this->image_id) {
+ if (!$this->image_id || !$this->cover) {
return $default;
}
try {
- $cover = $this->cover ? url($this->cover->getThumb($width, $height, false)) : $default;
- } catch (\Exception $err) {
- $cover = $default;
+ return $this->cover->getThumb($width, $height, false) ?? $default;
+ } catch (Exception $err) {
+ return $default;
}
-
- return $cover;
}
/**
use Intervention\Image\Image as InterventionImage;
use Intervention\Image\ImageManager;
use League\Flysystem\WhitespacePathNormalizer;
-use Psr\SimpleCache\InvalidArgumentException;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\StreamedResponse;
class ImageService
{
- protected ImageManager $imageTool;
- protected Cache $cache;
- protected FilesystemManager $fileSystem;
-
protected static array $supportedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
- public function __construct(ImageManager $imageTool, FilesystemManager $fileSystem, Cache $cache)
- {
- $this->imageTool = $imageTool;
- $this->fileSystem = $fileSystem;
- $this->cache = $cache;
+ public function __construct(
+ protected ImageManager $imageTool,
+ protected FilesystemManager $fileSystem,
+ protected Cache $cache
+ ) {
}
/**
* Save image data for the given path in the public space, if possible,
* for the provided storage mechanism.
*/
- protected function saveImageDataInPublicSpace(Storage $storage, string $path, string $data)
+ protected function saveImageDataInPublicSpace(Storage $storage, string $path, string $data): void
{
$storage->put($path, $data);
*
* @throws Exception
*/
- public function getThumbnail(Image $image, ?int $width, ?int $height, bool $keepRatio = false, bool $shouldCreate = false): ?string
- {
+ public function getThumbnail(
+ Image $image,
+ ?int $width,
+ ?int $height,
+ bool $keepRatio = false,
+ bool $shouldCreate = false,
+ bool $canCreate = false,
+ ): ?string {
// Do not resize GIF images where we're not cropping
if ($keepRatio && $this->isGif($image)) {
return $this->getPublicUrl($image->path);
return $this->getPublicUrl($image->path);
}
- if (!$shouldCreate) {
+ if (!$shouldCreate && !$canCreate) {
return null;
}
// Check the image file exists
&& $disk->exists($imagePath)
// Check the file is likely an image file
- && strpos($disk->mimeType($imagePath), 'image/') === 0;
+ && str_starts_with($disk->mimeType($imagePath), 'image/');
}
/**
*/
protected function checkUserHasAccessToRelationOfImageAtPath(string $path): bool
{
- if (strpos($path, '/uploads/images/') === 0) {
+ if (str_starts_with($path, '/uploads/images/')) {
$path = substr($path, 15);
}
// Strip thumbnail element from path if existing
$originalPathSplit = array_filter(explode('/', $path), function (string $part) {
- $resizedDir = (strpos($part, 'thumbs-') === 0 || strpos($part, 'scaled-') === 0);
- $missingExtension = strpos($part, '.') === false;
+ $resizedDir = (str_starts_with($part, 'thumbs-') || str_starts_with($part, 'scaled-'));
+ $missingExtension = !str_contains($part, '.');
return !($resizedDir && $missingExtension);
});
$url = ltrim(trim($url), '/');
// Handle potential relative paths
- $isRelative = strpos($url, 'http') !== 0;
+ $isRelative = !str_starts_with($url, 'http');
if ($isRelative) {
- if (strpos(strtolower($url), 'uploads/images') === 0) {
+ if (str_starts_with(strtolower($url), 'uploads/images')) {
return trim($url, '/');
}
foreach ($potentialHostPaths as $potentialBasePath) {
$potentialBasePath = strtolower($potentialBasePath);
- if (strpos(strtolower($url), $potentialBasePath) === 0) {
+ if (str_starts_with(strtolower($url), $potentialBasePath)) {
return 'uploads/images/' . trim(substr($url, strlen($potentialBasePath)), '/');
}
}
// region-based url will be used to prevent http issues.
if (!$storageUrl && config('filesystems.images') === 's3') {
$storageDetails = config('filesystems.disks.s3');
- if (strpos($storageDetails['bucket'], '.') === false) {
+ if (!str_contains($storageDetails['bucket'], '.')) {
$storageUrl = 'https://' . $storageDetails['bucket'] . '.s3.amazonaws.com';
} else {
$storageUrl = 'https://s3-' . $storageDetails['region'] . '.amazonaws.com/' . $storageDetails['bucket'];