Skip to content

Commit

Permalink
Merge pull request #225 from jordanade/master
Browse files Browse the repository at this point in the history
Add tmp_disk option/functionality to allow use of remote src_disk in Croppa 7.
  • Loading branch information
sdebacker authored Sep 30, 2024
2 parents 09dc88f + ee55cb8 commit 7a6a7f9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ composer.lock
/node_modules
/yarn.lock
.idea
.phpunit.result.cache
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ Thus, if you have `<img src="{{ Croppa::url('file.jpg', 200) }}">`, the returned

#### Src images on S3, local crops

This is a good solution for a load balanced enviornment. Each app server will end up with it’s own cache of cropped images, so there is some wasted space. But the web server (Apache, etc) can still serve the crops directly on subsequent crop requests.
This is a good solution for a load balanced environment. Each app server will end up with it’s own cache of cropped images, so there is some wasted space. But the web server (Apache, etc) can still serve the crops directly on subsequent crop requests. A tmp_disk must also be defined to temporarily store the source image.

```php
// Croppa config.php
return [
'src_disk' => 's3',
'tmp_disk' => 'temp',
'crops_disk' => 'public',
'path' => 'storage/(.*)$',
];
Expand Down
9 changes: 9 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
*/
'crops_disk' => 'public',

/*
* If using a remote src_disk, a local disk must be specified where remote
* source images are temporarily copied.
* (The Intervention Image library can't download remote images -
* see: https://image.intervention.io/v3/introduction/upgrade)
* Set to false/null/empty-string to disable.
*/
'tmp_disk' => 'public',

/*
* Maximum number of sizes to allow for a particular source file. This is to
* limit scripts from filling up your hard drive with images. Set to false or
Expand Down
62 changes: 57 additions & 5 deletions src/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ final class Storage
*/
private $srcDisk;

/**
* @var ?FilesystemAdapter
*/
private $tmpDisk;

/**
* @var bool
*/
private $tmpPath = '';

/**
* Inject dependencies.
*/
Expand Down Expand Up @@ -84,6 +94,26 @@ public function getSrcDisk(): FilesystemAdapter
return $this->srcDisk;
}

/**
* Set the tmp disk.
*/
public function setTmpDisk(FilesystemAdapter $disk): void
{
$this->tmpDisk = $disk;
}

/**
* Get the tmp disk or make via the config.
*/
public function getTmpDisk(): FilesystemAdapter
{
if (empty($this->tmpDisk)) {
$this->setTmpDisk($this->makeDisk($this->config['tmp_disk']));
}

return $this->tmpDisk;
}

/**
* "Mount" disks given the config.
*/
Expand Down Expand Up @@ -124,13 +154,23 @@ public function cropExists(string $path): bool
*/
public function path(string $path): string
{
$disk = $this->getSrcDisk();
if ($disk->fileExists($path)) {
if ($disk->getAdapter() instanceof LocalFilesystemAdapter) {
return $disk->path($path);
$srcDisk = $this->getSrcDisk();
if ($srcDisk->fileExists($path)) {
if ($srcDisk->getAdapter() instanceof LocalFilesystemAdapter) {
return $srcDisk->path($path);
}

// If a tmp_disk has been configured, copy file from remote srcDisk to tmpDisk
if ($this->config['tmp_disk']) {
$tmpDisk = $this->getTmpDisk();
$tmpDisk->writeStream($path, $srcDisk->readStream($path));
$this->tmpPath = $path;
return $tmpDisk->path($path);
}

return $disk->url($path);
// With Intervention 3, this will lead to a DecoderException ("Unable to decode input")
// We should probably throw an exception here to inform the developer that a tmp_disk is required.
return $srcDisk->url($path);
}

throw new NotFoundHttpException('Croppa: Src image is missing');
Expand All @@ -148,6 +188,18 @@ public function writeCrop(string $path, string $contents): void
} catch (FilesystemException $e) {
// don't throw exception anymore as mentioned in PR #164
}
$this->cleanup();
}

/**
* Cleanup: delete tmp file if required.
*/
public function cleanup(): void
{
if ($this->tmpPath <> '') {
$this->getTmpDisk()->delete($this->tmpPath);
$this->tmpPath = '';
}
}

/**
Expand Down

0 comments on commit 7a6a7f9

Please sign in to comment.